加入收藏 | 设为首页 | 会员中心 | 我要投稿 汽车网 (https://www.0577qiche.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

JAVA中计算两个日期时间的差值居然也有这么多门道

发布时间:2023-04-03 12:40:24 所属栏目:教程 来源:
导读:上半年春招的时候,作为面试官,对于面试表现的不错的同学会要求其写一小段代码看看。题目很简单:

给定一个日期,然后计算下距离今天相差的天数。

本以为这么个问题就是用来活跃面试氛围的,但是结果却让人大
上半年春招的时候,作为面试官,对于面试表现的不错的同学会要求其写一小段代码看看。题目很简单:

给定一个日期,然后计算下距离今天相差的天数。

本以为这么个问题就是用来活跃面试氛围的,但是结果却让人大跌眼镜,真正能写出来的人竟然寥寥无几,很多人写了一整张A4纸都写不下,最后还是没写完...他们在做什么?

先取出今天的日期,然后分别计算得出年、月、日的值,然后将给定的字符串进行切割,得到目标的年、月、日,然后再判断是否闰年之类的逻辑,决定每月应该是加28天还是29天还是30或者31天,最后得出一个天数!

日期时间的处理,是软件开发中极其常见的场景,JAVA中与日期、时间相关的一些类与API方法也很多,这里结合平时的编码实践全面的整理了下,希望可以帮助大家厘清其中的门道,更加游刃有余的面对此方面的处理~

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

java.time包中
JAVA8之后新增了java.time包,提供了一些与日期时间有关的新实现类:

具体每个类对应的含义说明梳理如下表:

类名    含义说明
LocalDate    获取当前的日期信息,仅有简单的日期信息,不包含具体时间、不包含时区信息。
LocalTime    获取当前的时间信息,仅有简单的时间信息,不含具体的日期、时区信息。
LocalDateTime    可以看做是LocalDate和LocalTime的组合体,其同时含有日期信息与时间信息,但是依旧不包含任何时区信息。
OffsetDateTime    在LocalDateTime基础上增加了时区偏移量信息
zoneddatetime    在OffsetDateTime基础上,增加了时区信息
ZoneOffset    时区偏移量信息, 比如+8:00或者-5:00等
ZoneId    具体的时区信息,比如Asia/Shanghai或者America/Chicago

时间间隔计算
Period与Duration类
JAVA8开始新增的java.time包中有提供Duration和Period两个类,用于处理日期时间间隔相关的场景,两个类的区别点如下:

类    描述
Duration    时间间隔,用于秒级的时间间隔计算
Period    日期间隔,用于天级别的时间间隔计算,比如年月日维度的
Duration与Period具体使用的时候还需要有一定的甄别,因为部分的方法很容易使用中被混淆,下面分别说明下。

Duration
Duration的最小计数单位为纳秒,其内部使用seconds和nanos两个字段来进行组合计数表示duration总长度。

Duration的常用API方法梳理如下:

方法    描述
between    计算两个时间的间隔,默认是秒
ofXxx    以of开头的一系列方法,表示基于给定的值创建一个Duration实例。比如ofHours(2L),则表示创建一个Duration对象,其值为间隔2小时
plusXxx    以plus开头的一系列方法,用于在现有的Duration值基础上增加对应的时间长度,比如plusDays()表示追加多少天,或者plusMinutes()表示追加多少分钟
minusXxx    以minus开头的一系列方法,用于在现有的Duration值基础上扣减对应的时间长度,与plusXxx相反
toXxxx    以to开头的一系列方法,用于将当前Duration对象转换为对应单位的long型数据,比如toDays()表示将当前的时间间隔的值,转换为相差多少天,而toHours()则标识转换为相差多少小时。
getSeconds    获取当前Duration对象对应的秒数, 与toXxx方法类似,只是因为Duration使用秒作为计数单位,所以直接通过get方法即可获取到值,而toDays()是需要通过将秒数转为天数换算之后返回结果,所以提供的方法命名上会有些许差异。
getNano    获取当前Duration对应的纳秒数“零头”。注意这里与toNanos()不一样,toNanos是Duration值的纳秒单位总长度,getNano()只是获取不满1s剩余的那个零头,以纳秒表示。
isNegative    检查Duration实例是否小于0,若小于0返回true, 若大于等于0返回false
isZero    用于判断当前的时间间隔值是否为0 ,比如比较两个时间是否一致,可以通过between计算出Duration值,然后通过isZero判断是否没有差值。
withSeconds    对现有的Duration对象的nanos零头值不变的情况下,变更seconds部分的值,然后返回一个新的Duration对象
withNanos    对现有的Duration对象的seconds值不变的情况下,变更nanos部分的值,然后返回一个新的Duration对象
关于Duration的主要API的使用,参见如下示意:

public void testDuration() {
    LocalTime target = LocalTime.parse("00:02:35.700");
    // 获取当前日期,此处为了保证后续结果固定,注掉自动获取当前日期,指定固定日期
    // LocalDate today = LocalDate.Now();
    LocalTime today = LocalTime.parse("12:12:25.600");
    // 输出:12:12:25.600
    System.out.println(today);
    // 输出:00:02:35.700
    System.out.println(target);
    Duration duration = Duration.between(target, today);
    // 输出:PT12H9M49.9S
    System.out.println(duration);
    // 输出:43789
    System.out.println(duration.getSeconds());
    // 输出:900000000
    System.out.println(duration.getNano());
    // 输出:729
    System.out.println(duration.toMinutes());
    // 输出:PT42H9M49.9S
    System.out.println(duration.plusHours(30L));
    // 输出:PT15.9S
    System.out.println(duration.withSeconds(15L));
}

(编辑:汽车网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章