首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java TimeUnit.MILLISECONDS.toDays()给出错误的结果

Java TimeUnit.MILLISECONDS.toDays()给出错误的结果
EN

Stack Overflow用户
提问于 2014-02-03 09:12:44
回答 4查看 8.3K关注 0票数 7

我在试着计算两天的差额。由于某种原因,比较01-03-2013和01-04-2013得出了结果30,以及01-03-2013和31-03-2013的比较结果。

代码语言:javascript
复制
Calendar cal = Calendar.getInstance();
cal.clear();

cal.set(2013, Calendar.MARCH, 1);
Date start = cal.getTime();

cal.set(2013, Calendar.APRIL, 1);
Date end = cal.getTime();

long days = TimeUnit.MILLISECONDS.toDays(end.getTime() - start.getTime());
System.out.println("!!! Amount of days : " + String.valueOf(days));

>> 30

cal.set(2013, Calendar.MARCH, 1);
start = cal.getTime();

cal.set(2013, Calendar.MARCH, 31);
end = cal.getTime();

days = TimeUnit.MILLISECONDS.toDays(end.getTime() - start.getTime());
System.out.println("!!! Amount of days : " + String.valueOf(days));

>> 30

为什么会这样呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-03 09:33:01

如果在3月31日你的时区开始日光节约,你就会得到这些结果。

从3月1日到4月1日,你有30个24小时的白天和一个23小时的一天,因为夏令的开始。如果你把毫秒的总数除以24x60x60x1000,你将得到30加23/24。四舍五入到30。

票数 9
EN

Stack Overflow用户

发布于 2014-02-03 09:58:46

时区

大卫·华莱士的正确答案解释说,夏令时或其他异常会影响代码的结果。依赖默认时区(或完全忽略时区)将使您陷入这种麻烦。

使Span具有包容性-排他性

另外,定义时间跨度的正确方法是使开头包含和结束是唯一的。所以,如果你想要三月,你需要从第一天的第一分钟到3月(4月1日)之后的第一天的第一分钟。

有关这个想法的冗长讨论,请参阅我的其他答案,如这一个这一个

这是我从其他答案中提取出来的一张图表:

尤达-时间

与Java捆绑在一起的java.util.Date/Calendar类是众所周知的麻烦。避开他们。使用Joda-Time,或者在Java 8中使用新的java.time.*包(受Joda-Time的启发)。

尤达-时间 2.3库提供了专门用于跨时间的类:周期、持续时间和间隔。该库还有一些方便的静态实用程序方法,如Days.daysBetween

Joda- time的DateTime对象确实知道自己的时区,与java.util.Date/Calendar不同,后者似乎有时区,但没有。

代码语言:javascript
复制
// Specify a timezone rather than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );

DateTime marchFirst = new DateTime( 2013, DateTimeConstants.MARCH, 1, 0, 0, 0, timeZone );
DateTime aprilFirst = new DateTime( 2013, DateTimeConstants.APRIL, 1, 0, 0, 0, timeZone );

int days = Days.daysBetween( marchFirst, aprilFirst).getDays();

转储到控制台…

代码语言:javascript
复制
System.out.println( "marchFirst: " + marchFirst );
System.out.println( "aprilFirst: " + aprilFirst ); // Note the change in time zone offset in the output.
System.out.println( "days: " + days );

跑步时,注意:

  • 正确答案: 31
  • 由于法国的夏令时,时区偏移的差异。
代码语言:javascript
复制
marchFirst: 2013-03-01T00:00:00.000+01:00
aprilFirst: 2013-04-01T00:00:00.000+02:00
days: 31
票数 1
EN

Stack Overflow用户

发布于 2014-02-03 09:24:06

我在我的系统中执行了相同的代码,它为我提供了如下输出:

代码语言:javascript
复制
!!! Amount of days : 31

请再检查一遍你的密码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21523357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档