java提供了Date和Calendar来处理时间,日期的类,包括创建日期,时间对象,获取系统当前日期和时间等一系列的操作
一、Date类
1.Date():生成一个当前时间的Date对象,改构造器在底层调用System.currentTimeMillis()获取long整数作为日期参数
2.Date(long date):指定long型的整数来生成一个Date对象
3.boolean before(Date when):测试该日期是否在指定日期when之前
4.boolean after(Date when):测试该日期是否在指定日期之后
5.void getTime():返回该对象的时间
6.void setTime()设置Date对象的时间
import javax.xml.crypto.Data;
public class Test{
public static void main(String[] args){
Date d1 = new Date();
Date d2 = new Date(System.currentTimeMillis() + 100);
System.out.println(d1);
System.out.println(d2);
System.out.println(d1.compareTo(d2));
System.out.println(d1.before(d2));
}
}
二、Calendar类
1.如果需要设置时间的增减可以考虑使用Calendar
2.由于Calendar是一个抽象类,所以不能实例化,也不能使用构造器去创建对象
3.Calendar类使用自身提供的getInstance()方法获取Calendar对象
常用的方法
1.void add(int field,int amount)根据日立的字段名(field)来增加和减少
2.void roll(int field,int amount)与add类似,只不过当设置了amount时,不会超过其他字段的最大限度,只会将该字段进行修改
3.int get(int field)后去日历中的某一字段
4.void set(int field,int value)为特定的字段设置给定值
void set(x,x,x,x,x,x)直接输入年月日时分秒
5.getTime()获取时间
package day04; import javax.xml.crypto.Data; import java.util.Calendar; public class Test { public static void main(String[] args) { //1.Calendar提供的getInstance()来获取 Calendar c = Calendar.getInstance();//获取Calendar对象 //int get()取出指定日历字段的值 System.out.println(c.get(Calendar.YEAR));//取出年 System.out.println(c.get(Calendar.MONTH));//取出月 System.out.println(c.get(Calendar.DATE));//取出日 //void set()设置字段值 // void set(m)指定字段 //void set(x,x,x,x,x,x)年月日时分秒 c.set(1998,11,12,12,23,54); //getTime()获取时间 System.out.println(c.getTime()); //void add(field,amount)根据日立的规则向前或向后指定的时间量 c.add(Calendar.YEAR,-1); System.out.println(c.getTime()); //void roll(field,amount)与 // add方法相似,区别在与家了amount后超过了该字段所表达的范围,也不会向上一字段进位 c.roll(Calendar.MONTH,4); System.out.println(c.getTime()); } }
说明:
c.set(1998,11,12,12,23,54);//1998-11-12
c.roll(Calendar.MONTH,6)//1998-5-12
c.add(Calendar.MONTH,6)//1999-5-12
三、正则表达式
Java提供了Pattern和Matcher两个类用于提供正则表达式的支持
在正则表达式中,如果直接给出字符,就是精确匹配。用\d
可以匹配一个数字,\w
可以匹配一个字母或数字,所以:
'00\d'
可以匹配'007'
,但无法匹配'00A'
;'\d\d\d'
可以匹配'010'
;'\w\w\d'
可以匹配'py3'
;
.
可以匹配任意字符,所以:
-
'py.'
可以匹配'pyc'
、'pyo'
、'py!'
等等。
要匹配变长的字符,在正则表达式中,用*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示n-m个字符:
来看一个复杂的例子:\d{3}\s+\d{3,8}
。
我们来从左到右解读一下:
\d{3}
表示匹配3个数字,例如'010'
;\s
可以匹配一个空格(也包括Tab等空白符),所以\s+
表示至少有一个空格,例如匹配' '
,' '
等;\d{3,8}
表示3-8个数字,例如'1234567'
。
综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。
如果要匹配'010-12345'
这样的号码呢?由于'-'
是特殊字符,在正则表达式中,要用'\'
转义,所以,上面的正则是\d{3}\-\d{3,8}
。
但是,仍然无法匹配'010 - 12345'
,因为带有空格。所以我们需要更复杂的匹配方式。
进阶
要做更精确地匹配,可以用[]
表示范围,比如:
[0-9a-zA-Z\_]
可以匹配一个数字、字母或者下划线;[0-9a-zA-Z\_]+
可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100'
,'0_Z'
,'Py3000'
等等;[a-zA-Z\_][0-9a-zA-Z\_]*
可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}
更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
A|B
可以匹配A或B,所以(P|p)ython
可以匹配'Python'
或者'python'
。
^
表示行的开头,^\d
表示必须以数字开头。
$
表示行的结束,\d$
表示必须以数字结束。
你可能注意到了,py
也可以匹配'python'
,但是加上^py$
就变成了整行匹配,就只能匹配'py'
了。
匹配开头和结尾
用正则表达式进行多行匹配时,我们用^
表示开头,$
表示结尾。例如,^A\d{3}$
,可以匹配"A001"
、"A380"
。
^和$----->多行匹配
^单独代表非
匹配指定范围
如果我们规定一个7~8位数字的电话号码不能以0
开头,应该怎么写匹配规则呢?\d{7,8}
是不行的,因为第一个\d
可以匹配到0
。
使用[...]
可以匹配范围内的字符,例如,[123456789]
可以匹配1
~9
,这样就可以写出上述电话号码的规则:[123456789]\d{6,7}
。
把所有字符全列出来太麻烦,[...]
还有一种写法,直接写[1-9]
就可以。
要匹配大小写不限的十六进制数,比如1A2b3c
,我们可以这样写:[0-9a-fA-F]
,它表示一共可以匹配以下任意范围的字符:
-
0-9
:字符0
~9
; -
a-f
:字符a
~f
; -
A-F
:字符A
~F
。
如果要匹配6位十六进制数,前面讲过的{n}
仍然可以继续配合使用:[0-9a-fA-F]{6}
。
[...]
还有一种排除法,即不包含指定范围的字符。假设我们要匹配任意字符,但不包括数字,可以写[^1-9]{3}
:
- 可以匹配
"ABC"
,因为不包含字符1
~9
; - 可以匹配
"A00"
,因为不包含字符1
~9
; - 不能匹配
"A01"
,因为包含字符1
; - 不能匹配
"A05"
,因为包含字符5
。
或规则匹配
用|
连接的两个正则规则是或规则,例如,AB|CD
表示可以匹配AB
或CD
。
它可以匹配"java"
或"php"
,但无法匹配"go"
。
要把go
也加进来匹配,可以改写为java|php|go
。
使用括号
现在我们想要匹配字符串learn java
、learn php
和learn go
怎么办?一个最简单的规则是learn\sjava|learn\sphp|learn\sgo
,但是这个规则太复杂了,可以把公共部分提出来,然后用(...)
把子规则括起来表示成learn\\s(java|php|go)
。
实际上(...)
还有一个重要作用,就是分组匹配。
我们来看一下如何用正则匹配区号-电话号
码这个规则。利用前面讲到的匹配规则,写出来很容易:
\d{3,4}\-\d{6,8}
虽然这个正则匹配规则很简单,但是往往匹配成功后,下一步是提取区号和电话号码,分别存入数据库。于是问题来了:如何提取匹配的子串?
当然可以用String
提供的indexOf()
和substring()
这些方法,但它们从正则匹配的字符串中提取子串没有通用性,下一次要提取learn\s(java|php)
还得改代码。
正确的方法是用(...)
先把要提取的规则分组,把上述正则表达式变为(\d{3,4})\-(\d{6,8})
。
现在问题又来了:匹配后,如何按括号提取子串?
现在我们没办法用String.matches()
这样简单的判断方法了,必须引入java.util.regex
包,用Pattern
对象匹配,匹配后获得一个Matcher
对象,如果匹配成功,就可以直接从Matcher.group(index)
返回子串:
public class Main {
public static void main(String[] args) {
Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
Matcher m = p.matcher("010-12345678");
if (m.matches()) {
String g1 = m.group(1);
String g2 = m.group(2);
System.out.println(g1);
System.out.println(g2);
} else {
System.out.println("匹配失败!");
}
}
}