转自 http://book.51cto.com/art/200907/140702.htm
11.5 日期操作类
在程序的开发中经常会遇到日期类型的操作,在Java中对于日期的操作也提供了良好的支持,主要使用java.util包中的Date、Calendar以及java.text包中的SimpleDateFormat。下面介绍其具体的用法。
11.5.1 Date类
Date类是一个较为简单的操作类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个完整的日期,构造方法定义如下:
1. public Date()
范例:得到当前系统日期
1. package org.lxh.demo11.datedemo;
2. import java.util.Date;
3. public class DateDemo01 {
4. public static void main(String[] args) {
5. Date date = new Date() ;
// 实例化Date类对象
6. System.out.println("当前日期为:"+date);
// 输出日期
7. }
8. }
程序运行结果:
当前日期为:Sun Oct 19 09:43:32 CST 2008
从程序的运行结果看,已经得到了系统的当前日期,但是对于此日期可以发现格式并不是很符合平常看到的格式,而且现在的时间也不能准确地精确到毫秒,要想按照用户自己的格式显示时间可以使用Calendar类完成操作。
提示:Date类使用较多。
虽然以上程序中,使用Date显示的日期格式并不符合用户的要求,但是从实际的角度来看Date类的使用频率也是很高的,因为只要使用格式化的方式就可以直接将一个日期格式按照用户所需要的方式进行显示,这一点在随后的部分可以看到。
11.5.2 Calendar类
Calendar类可以将取得的时间精确到毫秒。但是,这个类本身是一个抽象类,从之前学习到的知识可以知道,如果要想使用一个抽象类,则必须依靠对象的多态性,通过子类进行父类的实例化操作,Calendar的子类是GregorianCalendar类。在Calendar中提供了表11-6所示的部分常量,分别表示日期的各个数字。
表11-6 Calendar类中的常量
序 号 | 常 量 | 类 型 | 描 述 |
1 | public static final int YEAR | int | 取得年 |
2 | public static final int MONTH | int | 取得月 |
3 | public static final int DAY_OF_MONTH | int | 取得日 |
4 | public static final int HOUR_OF_DAY | int | 取得小时, 24 小时制 |
5 | public static final int MINUTE | int | 取得分 |
6 | public static final int SECOND | int | 取得秒 |
7 | public static final int MILLISECOND | int | 取得毫秒 |
除了以上提供的全局常量外,Calendar还提供了一些常用方法,如表11-7所示。
表11-7 Calendar类中提供的方法
序 号 | 方 法 | 类 型 | 描 述 |
1 | public static Calendar getInstance() | 普通 | 根据默认的时区 实例化对象 |
2 | public boolean after(Object when) | 普通 | 判断一个日期是否在 指定日期之后 |
3 | public boolean before(Object when) | 普通 | 判断一个日期是否 在指定日期之前 |
4 | public int get(int field) | 普通 | 返回给定日历字段的值 |
下面通过以上方法取得一个系统的当前日期。
范例:取得系统的当前日期
1. package org.lxh.demo11.datedemo;
2. import java.util.Calendar;
3. import java.util.GregorianCalendar;
4. public class DateDemo02 {
5. public static void main(String[] args) {
6. Calendar calendar = null;
// 声明一个Calendar对象
7. calendar = new GregorianCalendar();
// 通过子类为其实例化
8. System.out.println("年:" + calendar.
get(Calendar.YEAR)); // 年
9. System.out.println("月:" + (calendar.
get(Calendar.MONTH) + 1));
10. // 月
11. System.out.println("日:" + calendar.
get(Calendar.DAY_OF_MONTH));
12. // 日
13. System.out.println("时:" + calendar.
get(Calendar.HOUR_OF_DAY));
14. // 时
15. System.out.println("分:" + calendar.
get(Calendar.MINUTE));
16. // 分
17. System.out.println("秒:" + calendar.
get(Calendar.SECOND));
18. // 秒
19. System.out.println("毫秒:" + calendar.
get(Calendar.MILLISECOND));
20. // 秒
21. }
22. }
程序运行结果:
年:2008
月:10
日:19
时:10
分:8
秒:3
毫秒:280
以上程序通过GregorianCalendar子类实例化Calendar类,然后通过Calendar类中的各种常量及方法取得系统的当前时间。
但是,如果按照以上的方式取得,代码会比较复杂,所以在Java中又提供了其他日期的类。
DateFormat:
11.5.3 DateFormat类
在java.util.Date类中实际上取得的时间是一个非常正确的时间。但是因为其显示的格式不理想,所以无法符合中国人的习惯要求,那么实际上此时就可以为此类进行格式化操作,变为符合于中国人习惯的日期格式。
另外,要提醒读者的是DateFormat类与MessageFormat类都属于Format类的子类,专门用于格式化数据使用。DateFormat类的定义如下:
1. public abstract class DateFormat
2. extends Format
从定义上看DateFormat类是一个抽象类,所以肯定无法直接实例化,但是在此抽象类中提供了一个静态方法,可以直接取得本类的实例,此类的常用方法如表11-8所示。
表11-8 DateFormat类的常用方法
序 号 | 方 法 | 类 型 | 描 述 |
1 | public static final DateFormat getDateInstance() | 普通 | 得到默认的对象 |
2 | public static final DateFormat getDateInstance(int style, Locale aLocale) | 普通 | 根据 Locale 得到对象 |
3 | public static final DateFormat getDateTimeInstance() | 普通 | 得到日期时间对象 |
4 | public static final DateFormat getDateTimeInstance(int dateStyle,int timeStyle,Locale aLocale) | 普通 | 根据 Locale 得到日期时间对象 |
以上4个方法可以构造DateFormat类的对象,但是发现以上方法中需要传递若干个参数,这些参数表示日期地域或日期的显示形式。下面通过几段代码来了解DateFormat类的操作。
范例:观察DateFormat中的默认操作
1. package org.lxh.demo11.datedemo;
2. import java.text.DateFormat;
3. import java.util.Date;
4. public class DateDemo03 {
5. public static void main(String[] args) {
6. DateFormat df1 = null;
// 声明DateFormat类对象
7. DateFormat df2 = null;
// 声明DateFormat类对象
8. df1 = DateFormat.getDateInstance();
// 取得日期
9. df2 = DateFormat.getDateTimeInstance(); // 取得日期时间
10. System.out.println("DATE:" +
df1.format(new Date()));// 格式化日期
11. System.out.println("DATETIME:" +
df2.format(new Date()));
12. }
13. }
程序运行结果:
DATE:2008-12-2
DATETIME:2008-12-2 16:25:11
从程序的运行结果中发现,第2个DATETIME显示了时间,但还不是比较合理的中文显示格式。如果想取得更加合理的时间,则必须在构造DateFormat对象时传递若干个参数。
范例:指定显示的风格
1. package org.lxh.demo11.datedemo;
2. import java.text.DateFormat;
3. import java.util.Date;
4. import java.util.Locale;
5. public class DateDemo04 {
6. public static void main(String[] args) {
7. DateFormat df1 = null;
// 声明DateFormat对象
8. DateFormat df2 = null;
// 声明DateFormat对象
9. df1 = DateFormat.getDateInstance
(DateFormat.YEAR_FIELD, new Locale(
10. "zh", "CN"));
// 取得日期,并设置日期显示风格
11. // 取得日期时间,设置日期的显示格式、
时间的显示格式
12. df2 = DateFormat.getDateTimeInstance
(DateFormat.YEAR_FIELD,
13. DateFormat.ERA_FIELD, new
Locale("zh", "CN"));
14. System.out.println("DATE:" + df1.format(new Date()));
15. System.out.println("DATETIME:" +
df2.format(new Date()));
16. }
17. }
程序运行结果:
DATE:2008年12月2日
DATETIME:2008年12月2日 下午04时30分29秒 CST
可以发现,以上的日期时间已经被格式化,格式是其默认的时间显示格式,但是如果现在要想得到用户自己需要的日期显示格式,则必须通过DateFormat的子类SimpleDateFormat类完成。
11.5.4 SimpleDateFormat类(1)
在项目开发中,会经常将一个日期格式转换为另外一种日期格式,例如,原日期为2008-10-19 10:11:30.345,转换后日期为2008年10月19日10时11分30秒345毫秒。从这两个日期可以发现,日期的数字完全一样,只是日期格式有所不同,要想实现转换就必须使用java.text包中的SimpleDateFormat类完成。
首先必须先定义出一个完整的日期转化模板,在模板中通过特定的日期标记可以将一个日期格式中的日期数字提取出来,日期格式化模板标记如表11-9所示。
表11-9 日期格式化模板标记
序 号 | 标 记 | 描 述 |
1 | y | 年,年份是 4 位数字, 所以需要使用 yyyy 表示 |
2 | M | 年中的月份,月份是两位数字, 所以需要使用 MM 表示 |
3 | d | 月中的天数,天数是两位数字, 所以需要使用 dd 表示 |
4 | H | 一天中的小时数( 24 小时), 小时是两位数字,使用 HH 表示 |
续表
序 号 | 标 记 | 描 述 |
5 | m | 小时中的分钟数, 分钟是两位数字,使用 mm 表示 |
6 | s | 分钟中的秒数, 秒是两位数字,使用 ss 表示 |
7 | S | 毫秒数,毫秒数是 3 位数字,使用 SSS 表示 |
此外,还需要SimpleDateFormat类中的方法才可以完成,SimpleDateFormat类的常用方法如表11-10所示。
表11-10 SimpleDateFormat类中的常用方法
序 号 | 方 法 | 类 型 | 描 述 |
1 | public SimpleDateFormat(String pattern) | 构造 | 通过一个指定的模板构造对象 |
2 | public Date parse(String source) throws ParseException | 普通 | 将一个包含日期的 字符串变为 Date 类型 |
3 | public final String format(Date date) | 普通 | 将一个 Date 类型按照指定 格式变为 String 类型 |
范例:格式化日期操作
1. package org.lxh.demo11.datedemo;
2. import java.text.ParseException;
3. import java.text.SimpleDateFormat;
4. import java.util.Date;
5. public class DateDemo05 {
6. public static void main(String[] args){
7. String strDate = "2008-10-19 10:11:30.345";
// 定义日期时间的字符串
8. // 准备第1个模板,从字符串中提取日期数字
9. String pat1 = "yyyy-MM-dd HH:mm:ss.SSS";
10. // 准备第2个模板,将提取后的日期数字变为指定的格式
11. String pat2 = "yyyy年MM月dd日HH时mm分ss秒SSS毫秒";
12. SimpleDateFormat sdf1 = new
SimpleDateFormat(pat1);// 实例化模板对象
13. SimpleDateFormat sdf2 = new
SimpleDateFormat(pat2);// 实例化模板对象
14. Date d = null;
15. try {
16. d = sdf1.parse(strDate);
// 将给定字符串中的日期提取出来
17. } catch (ParseException e) {
// 如果提供的字符串格式有错误,则进
18. 行异常处理
19. e.printStackTrace();
20. }
21. System.out.println(sdf2.format(d));// 将日期变为新的格式
22. }
23. }
程序运行结果:
2008年10月19日10时11分30秒345毫秒
以上程序中,首先使用第1个模板将字符串中表示的日期数字取出,然后再使用第2个模板将这些日期数字重新转化为新的格式表示。
11.5.4 SimpleDateFormat类(2)
U提示:SimpleDateFormat类经常用于将String变为Date型数据。
在实际的开发中,用户所输入的各个数据都是以String的方式进行接收的,所以此时为了可以正确地将String变为Date型数据,可以依靠SimpleDateFormat类完成。
范例:将String型数据变为Date型数据
1. package org.lxh.demo11.datedemo;
2. import java.text.SimpleDateFormat;
3. import java.util.Date;
4. public class StringDateDemo {
5. public static void main(String[] args)
throws Exception { // 所有异常
6. 抛出
7. String strDate = "2008-10-19 10:11:30.345";
// 定义日期时间的字符串
8. String pat = "yyyy-MM-dd HH:mm:ss.SSS";
// 定义模板
9. SimpleDateFormat sdf = new
SimpleDateFormat(pat); // 实例化模板对象
10. Date d = sdf.parse(strDate);
// 将给定字符串中的日期
11. 提取出来
12. System.out.println(d) ;
// 输出Date对象
13. }
14. }
程序运行结果:
Sun Oct 19 10:11:30 CST 2008
以上程序已经实现了String向Date的转型操作,这样的操作在讲解Java数据库编程时将会经常使用。
11.5.5 实例操作--取得完整日期
1.实现一:基于Calendar类
以上已经为读者清楚地介绍了如何取得一个系统的日期以及对日期格式的转化操作,但是如果所有的程序都按Calendar程序那样取得日期,则代码肯定会重复很多次,所以可以考虑单独去设计一个类,此类可以取得当前系统的日期时间。但是在使用Calendar类得到时间时有一个问题,例如,现在的月份是9月,正确的日期格式应该是09,但是因为得到日期的方法返回的是int类型,所以最终的返回结果是9,也就是说要想达到正确的显示效果,则必须在9前补一个0。
范例:设计一个取得日期的类,此类可以取得系统的当前时间和时间戳
1. package org.lxh.demo11.datedemo;
2. import java.util.Calendar;
3. import java.util.GregorianCalendar;
4. class DateTime {
5. private Calendar calendar = null;
// 定义一个Calendar对象,可以
6. 取得时间
7. public DateTime() {
8. this.calendar = new GregorianCalendar();//
通过Calendar类的子类实例化
9. }
10. public String getDate() { // 得到完整的日期,
格式为:yyyy-MM-dd HH:mm:ss.
11. SSS
12. // 考虑到程序要频繁修改字符串,所以使用StringBuffer提升性能
13. StringBuffer buf = new StringBuffer();
14. // 依次取得时间
15. buf.append(calendar.get(Calendar.YEAR)).append("-");
16. buf.append(this.addZero(calendar.get
(Calendar.MONTH) + 1, 2));
17. buf.append("-");
18. buf.append(this.addZero(calendar.get
(Calendar.DAY_OF_MONTH), 2));
19. buf.append(" ");
20. buf.append(this.addZero(calendar.get
(Calendar.HOUR_OF_DAY), 2));
21. buf.append(":");
22. buf.append(this.addZero(calendar.get
(Calendar.MINUTE), 2));
23. buf.append(":");
24. buf.append(this.addZero(calendar.get
(Calendar.SECOND), 2));
25. buf.append(".");
26. buf.append(this.addZero(calendar.get
(Calendar.MILLISECOND), 3));
27. return buf.toString();
28. }
29. // 得到完整的日期,格式为:yyyy年MM月dd日HH时mm分ss秒SSS毫秒
30. public String getDateComplete() {
31. StringBuffer buf = new StringBuffer();
32. buf.append(calendar.get(Calendar.YEAR)).append("年");
33. buf.append(this.addZero(calendar.get
(Calendar.MONTH) + 1, 2));
34. buf.append("月");
35. buf.append(this.addZero(calendar.get
(Calendar.DAY_OF_MONTH), 2));
36. buf.append("日 ");
37. buf.append(this.addZero(calendar.get
(Calendar.HOUR_OF_DAY), 2));
38. buf.append("时");
39. buf.append(this.addZero(calendar.get
(Calendar.MINUTE), 2));
40. buf.append("分");
41. buf.append(this.addZero(calendar.get
42. (Calendar.SECOND), 2));
43. buf.append("秒");
44. buf.append(this.addZero(calendar.get
(Calendar.MILLISECOND), 3));
45. buf.append("毫秒");
46. return buf.toString();
47. }
48. // 考虑到日期中有前导0,所以在此处加上了补零的方法
49. private String addZero(int num, int len) {
50. StringBuffer s = new StringBuffer();
51. s.append(num);
52. while (s.length() < len) { // 如果长度不足,则继续补0
53. s.insert(0, "0"); // 在第1个位置处补0
54. }
55. return s.toString();
56. }
57. public String getTimeStamp() { //
得到时间戳:yyyyMMddHHmmssSSS
58. StringBuffer buf = new StringBuffer();
59. buf.append(calendar.get(Calendar.YEAR));
60. buf.append(this.addZero(calendar.
get(Calendar.MONTH) + 1, 2));
61. buf.append(this.addZero(calendar.
get(Calendar.DAY_OF_MONTH), 2));
62. buf.append(this.addZero(calendar.
get(Calendar.HOUR_OF_DAY), 2));
63. buf.append(this.addZero(calendar.
get(Calendar.MINUTE), 2));
64. buf.append(this.addZero(calendar.
get(Calendar.SECOND), 2));
65. buf.append(this.addZero(calendar.
get(Calendar.MILLISECOND), 3));
66. return buf.toString();
67. }
68. };
69. public class DateDemo06 {
70. public static void main(String[] args) {
71. DateTime dt = new DateTime();
// 实例化DateTime对象
72. System.out.println("系统日期:" + dt.getDate());
73. System.out.println("中文日期::" + dt.getDateComplete());
74. System.out.println("时间戳:" + dt.getTimeStamp());
75. }
76. }
程序运行结果:
系统日期:2008-10-19 10:42:50.562
中文日期::2008年10月19日 10时42分50秒562毫秒
时间戳:20081019104250562
以上程序已经完成了设计的要求,但程序代码太长、太复杂,那么有没有更好的方式呢?实际上是有的,SimpleDateFormat类中可以对一个Date类型进行格式修改的方法,直接使用此方法就可以将一个当前日期的Date类型变为指定的日期格式。
2.实现二:基于SimpleDateFormat类
使用SimpleDateFormat类可以方便地把一个日期变为指定格式,所以直接使用此类操作是最简单、最合适的。
范例:修改之前的程序
1. package org.lxh.demo11.datedemo;
2. import java.text.SimpleDateFormat;
3. import java.util.Date;
4. class DateTime{
5. // 声明日期格式化操作对象,直接对new Date()进行实例化
6. private SimpleDateFormat sdf = null ;
7. // 得到完整的日期,格式为:yyyy-MM-dd HH:mm:ss.SSS
8. public String getDate(){
9. this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
10. return this.sdf.format(new Date()) ;
11. }
12. // 得到完整的日期,格式为:yyyy年MM月dd日HH时mm分ss秒SSS毫秒
13. public String getDateComplete(){
14. this.sdf = new SimpleDateFormat("yyyy年
MM月dd日 HH时mm分ss秒SSS毫秒");
15. return this.sdf.format(new Date()) ;
16. }
17. public String getTimeStamp(){ // 得到时间戳:yyyyMMddHHmmssSSS
18. this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
19. return this.sdf.format(new Date()) ;
20. }
21. };
22. public class DateDemo07 {
23. public static void main(String[] args) {
24. DateTime dt = new DateTime(); // 实例化DateTime对象
25. System.out.println("系统日期:" + dt.getDate());
26. System.out.println("中文日期::" + dt.getDateComplete());
27. System.out.println("时间戳:" + dt.getTimeStamp());
28. }
29. }
程序运行结果:
系统日期:2008-10-19 10:47:48.610
中文日期::2008年10月19日 10时47分48秒610毫秒
时间戳:20081019104748610
以上程序完成了与11.5.1节程序相同的功能,而且代码更为简单,所以读者日后在开发代码时一定要多多设计,灵活地运用各种方法,使程序的开发更为便捷。