转载请注明出处:http://blog.csdn.net/wl9739/article/details/51839502
自从JDK 1.0开始,Java就提供了Date来处理时间和日期,作为老古董自然有很多东西是过时的。然后出现了Calendar
来解决了很多问题,但是Calendar
使用比较复杂,并且有些反人类的地方。直到Java 8的出现,它吸收了Joda-Time库的经验,使得Java处理时间和日期变得比较”人性化”了。本篇就来谈谈Java中的Date、Calendar,以及SimpleDateFormat的使用。在Java中的时间和日期(下)里面再对比一下Java 8中的日期处理。
古老的Date
查看一下Date类的源码,可以看到6个构造方法中,有4个已经添加了@Deprecated
的标签了,剩下没过时的只有两个:
public Date() {
this(System.currentTimeMillis());
}
public Date(long var1) {
this.fastTime = var1;
}
其中,第一个构造方法调用的是System.currentTimeMillis()
方法,这个方法返回的是一个long整数,表示GMT 1970年1月1日 00:00:00到现在所经历的毫秒数。这个毫秒数我们暂且称之为milliseconds
值,这个值很重要,无论是在Date类中还是Calendar类中,milliseconds
值都是计算时间日期的基准。
怎么获得这个长整型的数呢?需要调用getTime()
方法,注意并不是调用toString()
方法,它们两者的差异可以重下面的代码中体现出来:
public static void main(String[] args) {
Date date = new Date();
System.out.println(date.getTime()); // 1467628171312
System.out.println(date.toString()); // Mon Jul 04 18:29:31 CST 2016
}
而第二个构造方法的参数,表示创建的Date对象与GMT 1970年1月1日 00:00:00的时间差。比如,3600 * 1000毫秒是一小时,那么我们用getTime()
来验证一下:
public static void main(String[] args) {
Date date = new Date(3600 * 1000);
System.out.println(date.getTime()); // 3600000
}
没问题,然后我们调用一下toString()
方法,看看返回的是什么:
public static void main(String[] args) {
Date date = new Date(3600 * 1000);
System.out.println(date.toString()); // Thu Jan 01 09:00:00 CST 1970
}
嗯?竟然是9点,为什么不是1点呢?怎么差了8个小时?有此疑问的童鞋都是看书不仔细的。而看书仔细的童鞋则会问“CST和GMT是什么关系”之类的。因为CST是指的北京时间
(China Standard Time),而GMT是指的是格林尼治标准时间
(Greenwich Mean Time)。由于北京处于东八区,比GMT早8小时,所以打印的时间指的是北京时间1970年1月1日上午9点。
谈完了构造方法,下面说说Date这个古老的类中可以使用的方法。
- getTime()
这个方法之前我们已经用到了,它返回的是从GMT 1970年1月1日 00:00:00到这个类创建的毫秒数。 - setTime(long time)
设置该Date对象的时间。参数time表示从GMT 1970年1月1日 00:00:00后的毫秒数。 - after(Date when)
测试该日期是否是在指定的日期(when)之后。 - before(Date when)
测试该日期是否是在指定的日期(when)之前。
一段代码解释上面的方法:
public static void main(String[] args) {
Date nowaday = new Date();
System.out.println(nowaday.getTime()); // 1467633231471
System.out.println(nowaday.toString()); // Mon Jul 04 19:53:51 CST 2016
Date date = new Date(3600 * 1000);
System.out.println(nowaday.before(date)); // false
System.out.println(nowaday.after(date)); // true
nowaday.setTime(3600 * 1000);
System.out.println(nowaday); // Thu Jan 01 09:00:00 CST 1970
}
Date类中的构造方法和常用的未过时的方法基本就是这些了。看了之后是不是觉得其实Date类能用的东西很少?很多日期的操作,比如获取年月日啊,取这周周一的日期啊什么的都很难实现,这时候就要使用到Calendar类,或者使用更牛逼的Java 8中的时间日期包。
庞大的Calendar
Calendar类的构造方法
与Date类不同,Calendar类是一个抽象类。其直接子类是GregorianCalendar
。既然Calendar类是抽象类,那么如获取Calendar对象呢?可以使用下面的代码来创建一个Calendar对象:
Calendar rightNow = Calendar.getInstance();
和Date一样,创建好对象之后,便包含了当前日期和时间的信息。
其实,getInstance()
这个静态方法还有三个重载方法,在源码中我们可以看到它们4个欢聚一堂的情景:
public static synchronized Calendar getInstance() {
return new GregorianCalendar();
}
public static synchronized Calendar getInstance(Locale locale) {
return new GregorianCalendar(locale);
}
public static synchronized Calendar getInstance(TimeZone timezone) {
return new GregorianCalendar(timezone);
}
public static synchronized Calendar getInstance(TimeZone timezone, Locale locale) {
return new GregorianCalendar(timezone, locale);
}
估计大家都能看出来,这4个重载方法的区别在于时区和地区的不同。而它们都是通过创建子类(GregorianCalendar)的对象来返回一个Calendar对象,这其实是多态的一种应用,也是设计模式中工厂模式的应用。也就是说,我们也可以像下面那样来创建一个Calendar对象:
Calendar myCalendar =