我正在尝试计算Android应用中任意两次给定时间之间的差异。为了完成这个任务,我使用了JodaTime和Period类以及Period的getYears(),getDays(),getHours(),getMinutes()和getSeconds()方法。但是,我意识到它正在给出日期的每个元素之间的绝对差异。例如,在2017-01-29 00:00:00 (yyyy-MM-dd HH:mm:ss)
和2018-01-28 00:00:00
日期调用我的函数将返回:
0 years
2 days
0 hours
0 minutes
0 seconds
何时应该在每个其他部分返回364 days
和零。当然,它是一个Android应用程序,所以我不打印它们,我分开处理显示器。我能够使用LocalDateTime和Duration.between在我的计算机上执行此操作,但我不能在这里使用这些类。我正在寻找一个修复我当前的方法(下面)或建议一个全新的方法。先感谢您。
我目前的职能:
public int[] getDifference(DateTime start, DateTime end){
Period p = new Period(start, end);
int[] differences = new int[5];
differences[0] = p.getYears();
differences[1] = p.getDays();
differences[2] = p.getHours();
differences[3] = p.getMinutes();
differences[4] = p.getSeconds();
return differences;
}
答案 0 :(得分:0)
为什么你会期待364天?阅读class doc for Period
。
public int getDays()
获取句点的days字段部分。
“现场部分”是这里的关键。 Period
是若干年,月,周,日,小时,分钟,秒和毫秒。例如,一年半有两个部分,年部分为1,月部分为6。
您的输出跳过月部分和周部分。
DateTime start = new DateTime ( 2017 , 1 , 29 , 0 , 0 , DateTimeZone.UTC );
DateTime stop = new DateTime ( 2018 , 1 , 28 , 0 , 0 , DateTimeZone.UTC );
Period p = new Period ( start , stop );
int[] differences = new int[ 7 ];
differences[ 0 ] = p.getYears ();
differences[ 1 ] = p.getMonths ();
differences[ 2 ] = p.getWeeks ();
differences[ 3 ] = p.getDays ();
differences[ 4 ] = p.getHours ();
differences[ 5 ] = p.getMinutes ();
differences[ 6 ] = p.getSeconds ();
System.out.println ( "differences: " + Arrays.toString ( differences ) );
运行时,我们会看到11个月,4周和2天。在MacOS El Capitan上的Java 8 Update 121中运行Joda-Time 2.8.2。
差异:[0,11,4,2,0,0,0]
您可能会考虑致电toStandardDays
。但这样做会导致异常(java.lang.UnsupportedOperationException
)说:“无法转换为天数,因为此期间包含的月份和月份长度不同”。
仅供参考:现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
在java.time中,未附加到时间轴的时间跨度表示为java.time.Period
中的年 - 月 - 天或java.time.Duration
中的小时 - 分 - 秒 - 纳秒。
LocalDate
类表示没有时间且没有时区的仅限日期的值。
java.time类使用工厂方法避开构造函数。
LocalDate start = LocalDate.of ( 2017 , 1 , 29 );
LocalDate stop = LocalDate.of ( 2018 , 1 , 28 );
Period period = Period.between ( start , stop );
System.out.println ( "period.toString(): " + period );
toString
在standard ISO 8601 format for durations中生成一段文字。我们在这里看到11个月零30天。显然Joda-Time和java.time的计数方式不同。在这里我们看到不同的结果Joda-Time计算周数,而java.time则没有。
period.toString():P11M30D
答案 1 :(得分:0)
您还应该设置适当的句点类型,因为您只想要特定的标准化为年,日,小时,分钟和秒,另请参阅javadoc。
LocalDateTime start = new LocalDateTime(2017, 1, 29, 0, 0);
LocalDateTime end = new LocalDateTime(2018, 1, 28, 0, 0);
Period p = new Period(start, end, PeriodType.yearDayTime().withMillisRemoved());
System.out.println(p); // P364D (what you expected)
此示例也适用于开始和结束类型DateTime
。
请注意,此代码示例(作为Joda-Time本身的类Period
)无法完全迁移到新的java.time
- Java-8中包含的API,因为后面的API无法处理日期持续时间和时间组件。它也不能指定周期类型,即不能像PeriodType
那样控制标准化。
答案 2 :(得分:0)
尝试更换
Period p = new Period(start, end);
使用
Period p = new Period(start, end, PeriodType.yearMonthDayTime());