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


public void calculateDurationDays(String targetDate) {LocalDate target = LocalDate.parse(targetDate);LocalDate today = LocalDate.now();System.out.println("today : " + today);System.out.println("target: " + target);long days = Duration.between(target, today).abs().toDays();System.out.println("相差:"+ days + "天");}运行后会报错:
today : 2022-07-07target: 2022-07-11Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit: Seconds at java.time.LocalDate.until(LocalDate.java:1614) at java.time.Duration.between(Duration.java:475) at com.veezean.demo5.DateService.calculateDurationDays(DateService.java:24)点击看下Duration.between源码,可以看到注释上明确有标注着,这个方法是用于秒级的时间段间隔计算,而我们这里传入的是两个天级别的数据,所以就不支持此类型运算,然后抛异常了 。

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

文章插图
 

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

文章插图
 
再看下使用Period的实现:
public void calculateDurationDays(String targetDate) {LocalDate target = LocalDate.parse(targetDate);LocalDate today = LocalDate.now();System.out.println("today : " + today);System.out.println("target: " + target);// 注意,此处写法错误!这里容易踩坑:long days = Math.abs(Period.between(target, today).getDays());System.out.println("相差:"+ days + "天");}执行结果:
today : 2022-07-07target: 2021-07-07相差:0天执行是不报错,但是结果明显是错误的 。这是因为getDays()并不会将Period值换算为天数,而是单独计算年、月、日,此处只是返回天数这个单独的值 。
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图
 
再看下面的写法:
public void calculateDurationDays(String targetDate) {LocalDate target = LocalDate.parse(targetDate);LocalDate today = LocalDate.now();System.out.println("today : " + today);System.out.println("target: " + target);Period between = Period.between(target, today);System.out.println("相差:"+ Math.abs(between.getYears()) + "年"+ Math.abs(between.getMonths()) + "月"+ Math.abs(between.getDays()) + "天");}结果为:
today : 2022-07-07target: 2021-07-11相差:0年11月26天所以说,如果想要计算两个日期之间相差的绝对天数,用Period不是一个好的思路 。
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图
 
计算日期差
  • 通过LocalDate来计算
LocalDate中的toEpocDay可返回当前时间距离原点时间之间的天数,可以基于这一点,来实现计算两个日期之间相差的天数:
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图
 
代码如下:
public void calculateDurationDays(String targetDate) {LocalDate target = LocalDate.parse(targetDate);LocalDate today = LocalDate.now();System.out.println("today : " + today);System.out.println("target: " + target);long days = Math.abs(target.toEpochDay() - today.toEpochDay());System.out.println("相差:" + days + "天");}结果为:
today : 2022-07-07target: 2021-07-11相差:361天
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图
 
  • 通过时间戳来计算
如果是使用的Date对象,则可以通过将Date日期转换为毫秒时间戳的方式相减然后将毫秒数转为天数的方式来得到结果 。需要注意的是通过毫秒数计算日期天数的差值时,需要屏蔽掉时分秒带来的误差影响 。
public void calculateDaysGap(Date start, Date end) {final long ONE_DAY_MILLIS = 1000L * 60 * 60 * 24;// 此处要注意,去掉时分秒的差值影响,此处采用先换算为天再相减的方式long gapDays = Math.abs(end.getTime()/ONE_DAY_MILLIS - start.getTime()/ONE_DAY_MILLIS);System.out.println(gapDays);}输出结果:
today : 2022-07-08target: 2021-07-11相差:362天
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图
 
  • 数学逻辑计算
分别算出年、月、日差值,然后根据是否闰年、每月是30还是31天等计数逻辑,纯数学硬怼方式计算 。
不推荐、代码略...
JAVA中计算两个日期时间的差值竟然也有这么多门道

文章插图


推荐阅读