类名 | 具体描述 |
---|---|
Date | Date对象算是JAVA中历史比较悠久的用于处理日期、时间相关的类了,但是随着版本的迭代演进,其中的众多方法都已经被弃用,所以 Date更多的时候仅被用来做一个数据类型使用 ,用于记录对应的日期与时间信息 |
Calender | 为了弥补Date对象在日期时间处理方法上的一些缺陷,JAVA提供了Calender抽象类来 辅助实现Date相关的一些日历日期时间的处理与计算 。 |
TimeZone | Timezone类提供了一些有用的方法用于 获取时区的相关信息 |
@Test void test06(){ Date date1 = new Date(); // 获取当前时间后 +100 ms时间 Date date2 = new Date(System.currentTimeMillis() + 100); System.out.println(date1); System.out.println(date1.compareTo(date2)); System.out.println(date1.before(date2)); } 复制代码
结果
Fri Jul 22 15:31:16 CST 2022 -1 true 复制代码
总体来说,Date是一个设计相当糟糕的类,因此Java官方 推荐尽量少用Date的构造器和方法 。
如果需要对日期、时间进行加减运算,或获取指定时间的年、月、日、时、分、秒信息,可使用Calendar工具类。
示例
@Test void test05(){ Calendar calendar = Calendar.getInstance(); // Calendar.YEAR 表示当前年 int year = calendar.get(Calendar.YEAR); // Calendar.MONTH表示月份,但是为了计算方便,是从0开始算,所以显示出来是月份 -1 的 int month = calendar.get(Calendar.MONTH); // Calendar.DAY_OF_MONTH 在这个月 的这一天 int dom = calendar.get(Calendar.DAY_OF_MONTH); // Calendar.DAY_OF_YEAR 在这一年 的这一天 int doy = calendar.get(Calendar.DAY_OF_YEAR); // Calendar.DAY_OF_WEEK 在这一周 的这一天,从星期日当第一天从1开始算的,所以会是 +1 int dow = calendar.get(Calendar.DAY_OF_WEEK); // Calendar.DAY_OF_WEEK_IN_MONTH 在这一个月 这一天在 第几周 int dowim = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH); System.out.println(year+"年"+ month+"月"); System.out.println(dom+"日"); System.out.println(doy+"日"); System.out.println(dow+"日"); System.out.println(dowim); } 复制代码
结果
2022年6月20日11时8分19秒859毫秒 AM_PM: 0 HOUR: 11 DAY_OF_MONTH: 20日 DAY_OF_YEAR: 201日 DAY_OF_WEEK: 4日 DAY_OF_WEEK_IN_MONTH: 3 复制代码
具体可以看Calendar的静态属性,不需要刻意记
常用api
Calendar类提供了大量访问、修改日期时间的方法,常用方法如下:
方法 | 描述 |
---|---|
void add(int field, int amount) | 根据日历的规则,为给定的日历字段添加或减去指定的时间量。 |
int get(int field) | 返回指定日历字段的值。 |
int getActualMaximum(int field) | 返回指定日历字段可能拥有的最大值。例如月,最大值为11。 |
int getActualMinimum(int field) | 返回指定日历字段可能拥有的最小值。例如月,最小值为0。 |
void roll(int field, int amount) | 与add()方法类似,区别在于加上 amount后超过了该字段所能表示的最大范围时,也不会向上一个字段进位。 |
void set(int field, int value) | 将给定的日历字段设置为给定值。 |
void set(int year, int month, int date) | 设置Calendar对象的年、月、日三个字段的值。 |
void set(int year, int month, int date, int hourOfDay, int minute, int second) | 设置Calendar对象的年、月、日、时、分、秒6个字段的值。 |
上面的很多方法都需要一个int类型的field参数, field是Calendar类的类变量,如 Calendar.YEAR、Calendar.MONTH等分别代表了年、月、日、小时、分钟、秒等时间字段。**需要指出的是, Calendar.MONTH字段代表月份,月份的起始值不是1,而是O,所以要设置8月时,用7而不是8。**如上面演示的程序就示范了Calendar类的常规用法。
add和roll的区别
add
add(int field, int amount)的功能非常强大,add主要用于改变Calendar的特定字段的值。
具体的field操作可以看: Calendar的add()方法介绍
add(int field, int amount)有如下 两条规则:
@Test void test07(){ Calendar cal1 = Calendar.getInstance(); // 2003-8-23 cal1.set(2003, 7, 23, 0, 0, 0); // 2003-8-23 => 2004-2-23 cal1.add(Calendar.MONTH, 6); System.out.println(cal1.getTime()); Calendar cal2 = Calendar.getInstance(); // 2003-8-31 cal2.set(2003, 7, 31, 0, 0, 0); // 因为进位后月份改为2月,2月没有31日,自动变成29日,若不是闰年则变成28日 // 2003-8-31 => 2004-2-29 cal2.add(Calendar.MONTH, 6); System.out.println(cal2.getTime()); } 复制代码
对于上面的例子,8-31就会变成2-29。**因为MONTH 的下一级字段是DATE,从31到29改变最小(若不是闰年则变成28日)。**所以上面2003-8-31的MONTH字段增加6后,不是变成2004-3-2,而是变成2004-2-29。
结果
Mon Feb 23 00:00:00 CST 2004 Sun Feb 29 00:00:00 CST 2004 复制代码
roll
roll()的规则与add()的处理规则不同—— 当被修改的字段超出它允许的范围时,上一级字段不会增大。
@Test void test08(){ Calendar cal1 = Calendar.getInstance(); // 2003-8-23 cal1.set(2003, 7, 23, 0, 0, 0); // 2003-8-23 => 2003-2-23 cal1.roll(Calendar.MONTH, 6); System.out.println(cal1.getTime()); Calendar cal2 = Calendar.getInstance(); cal2.set(2003, 7, 31, 0, 0, 0); // MONTH字段“进位”后变成2,2月没有31日 // YEAR字段不会改变,2003年2月只有28天 // 2003-8-31 => 2003-2-28 cal2.roll(Calendar.MONTH, 6); System.out.println(cal2.getTime()); } 复制代码
结果
Sun Feb 23 00:00:00 CST 2003 Fri Feb 28 00:00:00 CST 2003 复制代码
设置Calendar的容错性
调用Calendar对象的set()方法来改变指定时间字段的值时,有可能传入一个不合法的参数,例如为MONTH字段设置13,这将会导致怎样的后果呢?看如下程序:
@Test void test09(){ Calendar cal = Calendar.getInstance(); System.out.println(cal.getTime()); // ① 结果是Year字段+1,MONTH字段为1ÿ