Java日期时间
java.util包提供了Date类来封装当前的日期和时间。Date类提供两个构造函数来实例化Date对象。
第一个构造函数使用当前日期和时间来初始化对象。
Date()
第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
Date(longmillisec)
Date对象创建以后,可以调用下面的方法。
序号
方法和描述
1
booleanafter(Datedate)
若当调用此方法的Date对象在指定日期之后返回true,否则返回false。
2
booleanbefore(Datedate)
若当调用此方法的Date对象在指定日期之前返回true,否则返回false。
3
Objectclone()
返回此对象的副本。
4
intcompareTo(Datedate)
比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
5
intcompareTo(Objectobj)若obj是Date类型则操作等同于compareTo(Date)
。否则它抛出ClassCastException。
6
booleanequals(Objectdate)
当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
7
longgetTime()
返回自1970年1月1日00:00:00GMT以来此Date对象表示的毫秒数。
8
inthashCode()
返回此对象的哈希码值。
9
voidsetTime(longtime)
用自1970年1月1日00:00:00GMT以后时间毫秒数设置时间和日期。
10
StringtoString()
转换Date对象为String表示形式,并返回该字符串。
获取当前日期时间
Java中获取当前日期和时间很简单,使用Date对象的toString()方法来打印当前日期和时间,如下所示:
尝试一下
以上实例编译运行结果如下:
MonMay0409:51:52CDT2013
日期比较
Java使用以下三种方法来比较两个日期:
使用getTime()方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
使用方法before(),after()和equals()。例如,一个月的12号比18号早,则newDate(99,2,12).before(newDate(99,2,18))返回true。
使用compareTo()方法,它是由Comparable接口定义的,Date类实现了这个接口。
使用SimpleDateFormat格式化日期
SimpleDateFormat是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat允许你选择任何用户自定义日期时间格式来运行。例如:
尝试一下
以上实例编译运行结果如下:
CurrentDate:Sun2004.07.18at04:14:09PMPDT
简单的DateFormat格式化编码
时间模式字符串用来指定时间格式。在此模式中,所有的ASCII字母被保留为模式字母,定义如下:
字母
描述
示例
G
纪元标记
广告
y
四位年份
2001
M
月份
七月或07
d
一个月的日期
10
h
上午/下午(1~12)格式小时
12
H
一天中的小时(0~23)
22
m
分钟数
30
s
秒数
55
S
毫秒数
234
E
星期几
星期二
D
一年中的日子
360
F
一个月中第几周的周几
2(<>月第二个星期三)
w
一年中第几周
40
W
一个月中第几周
1
一个
上午/下午标记
下午
k
一天中的小时(1~24)
24
K
上午/下午(0~11)格式小时
10
z
时区
东部标准时间
'
文字定界符
定界符
"
单引号
`
使用printf格式化日期
printf方法可以很轻松地格式化时间和日期。使用两个字母格式,它以t开头并且以下面表格中的一个字母结尾。例如:
尝试一下
以上实例编译运行结果如下:
CurrentDate/Time:SatDec1516:37:57MST2012
如果你需要重复提供日期,那么利用这种方式来格式化它的每一部分就有点复杂了。因此,可以利用一个格式化字符串指出要被格式化的参数的索引。
索引必须紧跟在%后面,而且必须以$结束。例如:
尝试一下
以上实例编译运行结果如下:
Duedate:February09,2004
或者,你可以使用<标志。它表明先前被格式化的参数要被再次使用。例如:
尝试一下
以上实例编译运行结果如下:
Duedate:February09,2004
日期和时间转换字符
字符
描述
例子
c
完整的日期和时间
MonMay0409:51:52CDT2009
F
ISO8601格式日期
2004-02-09
D
U.S.格式日期(月/日/年)
02/09/2004
T
24小时时间
18:05:19
r
12小时时间
06:05:19pm
R
24小时时间,不包含秒
18:05
Y
4位年份(包含前导0)
2004
y
年份后2位(包含前导0)
04
C
年份前2位(包含前导0)
20
B
月份全称
二月
b
月份简称
2月
n
2位月份(包含前导0)
02
d
2位日子(包含前导0)
03
e
2位日子(不包含前导0)
9
一个
星期全称
星期一
一个
星期简称
星期一
j
3位年份(包含前导0)
069
H
2位小时(包含前导0),00到23
18
k
2位小时(不包含前导0),0到23
18
我
2位小时(包含前导0),01到12
06
l
2位小时(不包含前导0),1到12
6
M
2位分钟(包含前导0)
05
S
2位秒数(包含前导0)
19
L
3位毫秒(包含前导0)
047
N
9位纳秒(包含前导0)
047000000
P
大写上下午标志
下午
p
小写上下午标志
下午
z
从GMT的RFC822数字偏移
-0800
Z
时区
太平洋标准时间
s
自1970-01-0100:00:00GMT的秒数
1078884319
Q
自1970-01-0100:00:00GMT的毫妙
1078884319047
还有其他有用的日期和时间相关的类。对于更多的细节,你可以参考到Java标准文档。
解析字符串为时间
SimpleDateFormat类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat对象的格式化存储来解析字符串。例如:
尝试一下
以上实例编译运行结果如下:
Java休眠(sleep)
你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的任意段时间。例如,下面的程序会休眠3秒:
尝试一下
以上实例编译运行结果如下:
测量时间
下面的一个例子表明如何测量时间间隔(以毫秒为单位):
尝试一下
以上实例编译运行结果如下:
Calendar类
我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟?我们又如何在日期的这些部分加上或者减去值呢?答案是使用Calendar类。
Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。
Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
创建一个代表系统当前日期的Calendar对象
Calendarc=Calendar.getInstance();//默认是当前日期
创建一个指定日期的Calendar对象
使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。
Calendar类对象字段类型
Calendar类中用一下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想
常量
描述
Calendar.YEAR
年份
Calendar.MONTH
月份
Calendar.DATE
日期
Calendar.DAY_OF_MONTH
日期,和上面的字段意义完全相同
Calendar.HOUR
12小时制的小时
Calendar.HOUR_OF_DAY
24小时制的小时
Calendar.MINUTE
分钟
Calendar.SECOND
秒
Calendar.DAY_OF_WEEK
星期几
Calendar类对象信息的设置
Set设置
如:
Calendarc1=Calendar.getInstance();
调用:
publicfinalvoidset(intyear,intmonth,intdate)
c1.set(2009,6-1,12);//把Calendar对象c1的年月日分别设这为:2009、5、12
利用字段类型设置
如果只设定某个字段,例如日期的值,则可以使用如下set方法:
publicvoidset(intfield,intvalue)
把c1对象代表的日期设置为10号,其它所有的数值会被重新计算
c1.set(Calendar.DATE,10);
把c1对象代表的年份设置为2008年,其他的所有数值会被重新计算
c1.set(Calendar.YEAR,2008);
其他字段属性set的意义以此类推
Add设置
Calendarc1=Calendar.getInstance();
把c1对象的日期加上10,也就是c1所表的日期的10天后的日期,其它所有的数值会被重新计算
c1.add(Calendar.DATE,10);
把c1对象的日期减去10,也就是c1所表的日期的10天前的日期,其它所有的数值会被重新计算
c1.add(Calendar.DATE,-10);
其他字段属性的add的意义以此类推
Calendar类对象信息的获得
GregorianCalendar类
Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。
Calendar的getInstance()方法返回一个默认用当前的语言环境和时区初始化的GregorianCalendar对象。GregorianCalendar定义了两个字段:AD和BC。这些代表公历定义的两个时代。
下面列出GregorianCalendar对象的几个构造方法:
序号
构造函数和说明
1
GregorianCalendar()
在具有默认语言环境的默认时区内使用当前时间构造一个默认的GregorianCalendar。
2
GregorianCalendar(intyear,intmonth,intdate)
在具有默认语言环境的默认时区内构造一个带有给定日期设置的GregorianCalendar
3
GregorianCalendar(intyear,intmonth,intdate,inthour,intminute)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的GregorianCalendar。
4
GregorianCalendar(intyear,intmonth,intdate,inthour,intminute,intsecond)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的GregorianCalendar。
5
GregorianCalendar(LocaleaLocale)
在具有给定语言环境的默认时区内构造一个基于当前时间的GregorianCalendar。
6
GregorianCalendar(TimeZonezone)
在具有默认语言环境的给定时区内构造一个基于当前时间的GregorianCalendar。
7
GregorianCalendar(TimeZonezone,LocaleaLocale)
在具有给定语言环境的给定时区内构造一个基于当前时间的GregorianCalendar。
这里是GregorianCalendar类提供的一些有用的方法列表:
序号
方法和说明
1
voidadd(intfield,intamount)
根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。
2
protectedvoidcomputeFields()
转换UTC毫秒值为时间域值
3
protectedvoidcomputeTime()
覆盖Calendar,转换时间域值为UTC毫秒值
4
booleanequals(Objectobj)
比较此GregorianCalendar与指定的Object。
5
intget(intfield)
获取指定字段的时间值
6
intgetActualMaximum(intfield)
返回当前日期,给定字段的最大值
7
intgetActualMinimum(intfield)
返回当前日期,给定字段的最小值
8
intgetGreatestMinimum(intfield)
返回此GregorianCalendar实例给定日历字段的最高的最小值。
9
DategetGregorianChange()
获得格里高利历的更改日期。
10
intgetLeastMaximum(intfield)
返回此GregorianCalendar实例给定日历字段的最低的最大值
11
intgetMaximum(intfield)
返回此GregorianCalendar实例的给定日历字段的最大值。
12
DategetTime()
获取日历当前时间。
13
longgetTimeInMillis()
获取用长整型表示的日历的当前时间
14
TimeZonegetTimeZone()
获取时区。
15
intgetMinimum(intfield)
返回给定字段的最小值。
16
inthashCode()
重写hashCode.
17
booleanisLeapYear(intyear)
确定给定的年份是否为闰年。
18
voidroll(intfield,booleanup)
在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。
19
voidset(intfield,intvalue)
用给定的值设置时间字段。
20
voidset(intyear,intmonth,intdate)
设置年、月、日的值。
21
voidset(intyear,intmonth,intdate,inthour,intminute)
设置年、月、日、小时、分钟的值。
22
voidset(intyear,intmonth,intdate,inthour,intminute,intsecond)
设置年、月、日、小时、分钟、秒的值。
23
voidsetGregorianChange(Datedate)
设置GregorianCalendar的更改日期。
24
voidsetTime(Datedate)
用给定的日期设置Calendar的当前时间。
25
voidsetTimeInMillis(longmillis)
用给定的long型毫秒数设置Calendar的当前时间。
26
voidsetTimeZone(TimeZonevalue)
用给定时区值设置当前时区。
27
StringtoString()
返回代表日历的字符串。
实例
以上实例编译运行结果如下:
关于Calender类的完整列表,你可以参考标准的Java文档。
Java正则表达式
正则表达式定义了字符串的模式。
正则表达式可以用来搜索、编辑或处理文本。
正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
Java正则表达式和Perl的是最为相似的。
java.util.regex包主要包括以下三个类:
Pattern类:
pattern对象是一个正则表达式的编译表示。Pattern类没有公共构造方法。要创建一个Pattern对象,你必须首先调用其公共静态编译方法,它返回一个Pattern对象。该方法接受一个正则表达式作为它的第一个参数。
Matcher类:
Matcher对象是对输入字符串进行解释和匹配操作的引擎。与Pattern类一样,Matcher也没有公共构造方法。你需要调用Pattern对象的matcher方法来获得一个Matcher对象。
PatternSyntaxException:
PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
捕获组
捕获组是把多个字符当一个单独单元进行处理的方法,它通过对括号内的字符分组来创建。
例如,正则表达式(dog)创建了单一分组,组里包含"d","o",和"g"。
捕获组是通过从左至右计算其开括号来编号。例如,在表达式((A)(B(C))),有四个这样的组:
((A)(B(C)))
(A)
(B(C))
(C)
可以通过调用matcher对象的groupCount方法来查看表达式有多少个分组。groupCount方法返回一个int值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(组0),它总是代表整个表达式。该组不包括在groupCount的返回值中。
实例
下面的例子说明如何从一个给定的字符串中找到数字串:
以上实例编译运行结果如下:
正则表达式语法
字符
说明
\
将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,"n"匹配字符"n"。"\n"匹配换行符。序列"\\"匹配"\","\("匹配"("。
^
匹配输入字符串开始的位置。如果设置了RegExp对象的Multiline属性,^还会与"\n"或"\r"之后的位置匹配。
$
匹配输入字符串结尾的位置。如果设置了RegExp对象的Multiline属性,$还会与"\n"或"\r"之前的位置匹配。
*
零次或多次匹配前面的字符或子表达式。例如,zo*匹配"z"和"zoo"。*等效于{0,}。
一次或多次匹配前面的字符或子表达式。例如,"zo"与"zo"和"zoo"匹配,但与"z"不匹配。等效于{1,}。
?
零次或一次匹配前面的字符或子表达式。例如,"do(es)?"匹配"do"或"does"中的"do"。?等效于{0,1}。
{n}
n是非负整数。正好匹配n次。例如,"o{2}"与"Bob"中的"o"不匹配,但与"food"中的两个"o"匹配。
{n,}
n是非负整数。至少匹配n次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有o。"o{1,}"等效于"o"。"o{0,}"等效于"o*"。
{n,m}
M和n是非负整数,其中n<=m。匹配至少n次,至多m次。例如,"o{1,3}"匹配"fooooood"中的头三个o。'o{0,1}'等效于'o?'。注意:您不能将空格插入逗号和数字之间。
?
当此字符紧随任何其他限定符(*、、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o?"只匹配单个"o",而"o"匹配所有"o"。
.
匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。
(pattern)
匹配pattern并捕获该匹配的子表达式。可以使用$0…$9属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符(),请使用"\("或者"\)"。
(?:pattern)
匹配pattern但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符(|)组合模式部件的情况很有用。例如,'industr(?:y|ies)是比'industry|industries'更经济的表达式。
(?=pattern)
执行正向预测先行搜索的子表达式,该表达式匹配处于匹配pattern的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows(?=95|98|NT|2000)'匹配"Windows2000"中的"Windows",但不匹配"Windows3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
(?!pattern)
执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows(?!95|98|NT|2000)'匹配"Windows3.1"中的"Windows",但不匹配"Windows2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
x|y
匹配x或y。例如,'z|food'匹配"z"或"food"。'(z|f)ood'匹配"zood"或"food"。
[xyz]
字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。
[^xyz]
反向字符集。匹配未包含的任何字符。例如,"[^abc]"匹配"plain"中"p","l","i","n"。
[a-z]
字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。
[^a-z]
反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。
\b
匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。
\B
非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。
\cx
匹配x指示的控制字符。例如,\cM匹配Control-M或回车符。x的值必须在A-Z或a-z之间。如果不是这样,则假定c就是"c"字符本身。
\d
数字字符匹配。等效于[0-9]。
\D
非数字字符匹配。等效于[^0-9]。
\f
换页符匹配。等效于\x0c和\cL。
\n
换行符匹配。等效于\x0a和\cJ。
\r
匹配一个回车符。等效于\x0d和\cM。
\s
匹配任何空白字符,包括空格、制表符、换页符等。与[\f\n\r\t\v]等效。
\S
匹配任何非空白字符。与[^\f\n\r\t\v]等效。
\t
制表符匹配。与\x09和\cI等效。
\v
垂直制表符匹配。与\x0b和\cK等效。
\w
匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。
\W
与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。
\xn
匹配n,此处的n是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用ASCII代码。
\num
匹配num,此处的num是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。
\n
标识一个八进制转义码或反向引用。如果\n前面至少有n个捕获子表达式,那么n是反向引用。否则,如果n是八进制数(0-7),那么n是八进制转义码。
\nm
标识一个八进制转义码或反向引用。如果\nm前面至少有nm个捕获子表达式,那么nm是反向引用。如果\nm前面至少有n个捕获,则n是反向引用,后面跟有字符m。如果两种前面的情况都不存在,则\nm匹配八进制值nm,其中n和m是八进制数字(0-7)。
\nml
当n是八进制数(0-3),m和l是八进制数(0-7)时,匹配八进制转义码nml。
\un
匹配n,其中n是以四位十六进制数表示的Unicode字符。例如,\u00A9匹配版权符号(©)。
Matcher类的方法
索引方法
索引方法提供了有用的索引值,精确表明输入字符串中在哪能找到匹配:
序号
方法及说明
1
publicintstart()
返回以前匹配的初始索引。
2
publicintstart(intgroup)
返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引
3
publicintend()
返回最后匹配字符之后的偏移量。
4
publicintend(intgroup)
返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。
研究方法
研究方法用来检查输入字符串并返回一个布尔值,表示是否找到该模式:
序号
方法及说明
1
publicbooleanlookingAt()
尝试将从区域开头开始的输入序列与该模式匹配。
2
publicbooleanfind()
尝试查找与该模式匹配的输入序列的下一个子序列。
3
publicbooleanfind(intstart)
重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。
4
publicbooleanmatches()
尝试将整个区域与模式匹配。
替换方法
替换方法是替换输入字符串里文本的方法:
序号
方法及说明
1
publicMatcherappendReplacement(StringBuffersb,Stringreplacement)
实现非终端添加和替换步骤。
2
publicStringBufferappendTail(StringBuffersb)
实现终端添加和替换步骤。
3
publicStringreplaceAll(Stringreplacement)
替换模式与给定替换字符串相匹配的输入序列的每个子序列。
4
publicStringreplaceFirst(Stringreplacement)
替换模式与给定替换字符串匹配的输入序列的第一个子序列。
5
publicstaticStringquoteReplacement(Strings)
返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement方法一个字面字符串一样工作。
start和end方法
下面是一个对单词"cat"出现在输入字符串中出现次数进行计数的例子:
以上实例编译运行结果如下:
可以看到这个例子是使用单词边界,以确保字母"c""a""t"并非仅是一个较长的词的子串。它也提供了一些关于输入字符串中匹配发生位置的有用信息。
Start方法返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引,end方法最后一个匹配字符的索引加1。
matches和lookingAt方法
matches和lookingAt方法都用来尝试匹配一个输入序列模式。它们的不同是matches要求整个序列都匹配,而lookingAt不要求。
这两个方法经常在输入字符串的开始使用。
我们通过下面这个例子,来解释这个功能:
以上实例编译运行结果如下:
replaceFirst和replaceAll方法
replaceFirst和replaceAll方法用来替换匹配正则表达式的文本。不同的是,replaceFirst替换首次匹配,replaceAll替换所有匹配。
下面的例子来解释这个功能:
以上实例编译运行结果如下:
Thecatsaysmeow.Allcatssaymeow.
appendReplacement和appendTail方法
Matcher类也提供了appendReplacement和appendTail方法用于文本替换:
看下面的例子来解释这个功能:
以上实例编译运行结果如下:
-foo-foo-foo-
PatternSyntaxException类的方法
PatternSyntaxException是一个非强制异常类,它指示一个正则表达式模式中的语法错误。
PatternSyntaxException类提供了下面的方法来帮助我们查看发生了什么错误。
序号
方法及说明
1
publicStringgetDescription()
获取错误的描述。
2
publicintgetIndex()
获取错误的索引。
3
publicStringgetPattern()
获取错误的正则表达式模式。
4
publicStringgetMessage()
返回多行字符串,包含语法错误及其索引的描述、错误的正则表达式模式和模式中错误索引的可视化指示。