Java日期时间类及计算

1. Java中与日期相关的类

1.1 java.util包

类名 具体描述
Date Date对象算是JAVA中历史比较悠久的用于处理日期、时间相关的类了,但是随着版本的迭代演进,其中的众多方法都已经被弃用,所以 Date更多的时候仅被用来做一个数据类型使用 ,用于记录对应的日期与时间信息
Calender 为了弥补Date对象在日期时间处理方法上的一些缺陷,JAVA提供了Calender抽象类来 辅助实现Date相关的一些日历日期时间的处理与计算 。
TimeZone Timezone类提供了一些有用的方法用于 获取时区的相关信息

① Date类

@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
复制代码

② Calendar 日历类

总体来说,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.DAY_OF_MONTH 在这个月 的这一天,但是为了计算方便, 是从0开始算,所以显示出来是月份 -1 的
  • Calendar.DAY_OF_YEAR 在这一年 的这一天
  • Calendar.DAY_OF_WEEK 在这一周 的这一天, 从星期日当第一天从1开始算的,所以会是 +1
  • Calendar.DAY_OF_WEEK_IN_MONTH 在这一个月 这一天在 第几周
  • Calendar.HOUR 表示今天这一天的小时(0-11),分上午和下午

具体可以看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的特定字段的值。

  • 如果需要增加某字段的值,则让 amount为正数;
  • 如果需要减少某字段的值,则让 amount为负数即可。

具体的field操作可以看: Calendar的add()方法介绍

add(int field, int amount)有如下 两条规则:

  1. 当被修改的字段超出它允许的范围时,会发生进位,即上一级字段也会增大。
  2. 如果下一级字段也需要改变,那么该字段会修正到变化最小的值。
@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ÿ

你可能感兴趣的:(java,jvm,开发语言)