前言
此前Java处理时间日期所使用的 Date 和 Calendar 被诟病不已,Calendar 的主要问题对象可变,而像时间和日期这样的类应该是不可变的,另外其概念模型也有不明确的地方,月份计算从0开始等等。
JodaTime开源时间/日期库是很好的替代,另外Java8中也推出了新的java.time库,设计理念与JodaTime相似。
Joda-Time 令时间和日期值变得易于管理、操作和理解。易于使用是 Joda 的主要设计目标。Joda-Time主类 DateTime 和JDK旧有类 Date 和 Calendar之间可以互相转换。从而保证了与JDK框架的兼容。
本文主要介绍了下Period类及如何正确的两个时间的差值 通过分析构造方法的方式进行展开,详细见下文
常用操作
org.joda.time大部分用法计算机程序的思维逻辑和使用Joda-Time优雅的处理日期时间这里面都有很好的介绍不再赘述,下面主要看下处理时间段(两个日期的差值)的Period类
Period简介
由一组持续时间字段值指定的不可变时间段
一段时间分为多个字段如年月日来表示,这些字段由PeriodType类定义,PeriodType默认值为standard类型,支持年,月,周,日,小时,分钟,秒和毫秒
构造函数
1 | 第一种:直接声明 |
正确的获取两个时间之间的差值
网上有很多的案例说获取两个时间之间的差距年月日等信息的解决方案:
计算两个时间的差值
1
2
3
4
5
6 >DateTime start = new DateTime(2016,8,18,10,58);
>DateTime end = new DateTime(2016,9,19,12,3);
>Period period = new Period(start,end);
>System.out.println(period.getMonths()+"月"+period.getDays()+"天"
> +period.getHours()+"小时"+period.getMinutes()+"分");
>
输出为:
1
2
3 >1月1天1小时5分
>复制代码
>
只要给定起止时间,Period就可以自动计算出来,两个时间之间有多少月、多少天、多少小时等。
这里有一个问题没有说明 拿一个案例来说
1 | DateTime d1 = new DateTime(2018,1,27,0,30); |
输出为:
1 | 0年0月4周2天 |
是不是跟预期想要得到的30天不一致,下面看下原因
1 | 使用new Period(ReadableInstant var1, ReadableInstant var2)进行Period的实例化 |
所以获取两个日期的差值如年月日的正确姿势应该如下
1 | DateTime d1 = new DateTime(2018,1,27,0,30); |
输入结果:
1 | 0年0月0周30天 |
查询官方文档
1
2
3 > public Period(ReadableInstant startInstant,
> ReadableInstant endInstant)
>
Most calculations performed by this method have obvious results. The special case is where the calculation is from a “long” month to a “short” month. Here, the result favours increasing the months field rather than the days. For example, 2013-01-31 to 2013-02-28 is treated as one whole month. By contrast, 2013-01-31 to 2013-03-30 is treated as one month and 30 days (exposed as 4 weeks and 2 days). The results are explained by considering that the start date plus the calculated period result in the end date.
大致的意思是说有的两点:
2013-01-31 to 2013-03-30 is treated as one month and 30 days (exposed as 4 weeks and 2 days)
从2013-01-31到2013-03-30被视为有一个月和30天(其中30天暴露为4周和2天)
上面已经分析过原因及实现,以及如果获取到想要的值
从大月到小月的计算需要注意,比如2013-01-31到2013-02-28是一个月
2013-01-29到2013-02-28也是一个月
2013-01-28到2013-02-28还是一个月
2013-01-27到2013-02-28是一个月零一天
这个也是需要注意的点
总结
笔者也是在项目中使用joda.time来处理两个时间的差值的时候使用Period这个处理时间段的类,但是在使用的过程中出现了跟预期值不同的问题,随后翻阅资料更正了用法总结了一下,希望能够帮助到大家。需要使用到更多的用法可以参考官方文档:User Guide。