首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TimeUnit类坏了吗?

TimeUnit类坏了吗?
EN

Stack Overflow用户
提问于 2016-06-16 21:42:59
回答 1查看 129关注 0票数 2

我注意到TimeUnit类的一个奇怪行为,所以我创建了这个最小的例子来再现它。

代码语言:javascript
复制
long differenceInDays;

Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();

c1.setTimeInMillis(1466062306000l); // Thu Jun 16 2016 09:31:46 GMT+0200
c2.setTimeInMillis(1466028000000l); // Thu Jun 16 2016 00:00:00 GMT+0200

differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // obviously zero

c2.add(Calendar.DATE, +1);
differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // why zero and not one?

c2.add(Calendar.DATE, +1);
differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // suddenly a 1, but not a 2 like expected

很明显,第一次计算差额是0,因为日期之间没有一整天。

但是第二次整日加起来,怎么还能是0呢?

输出:

0 0 1

我不认为这个问题与夏令时或闰年有关,因为我只在同一年,甚至月份内进行计算。

这里是一个以毫秒为单位的计算器,供您检查。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-16 21:53:32

通过简单的数学,你可以更清楚地看到这里发生了什么:

代码语言:javascript
复制
c1 = 1466062306000
c2 = 1466028000000

d = 86400000                // one day

c2 - c1 = -34306000         // negative, but less than one day in magnitude
c2 - c1 + d = 52094000      // less than one day
c2 - c1 + d + d = 138494000 // more than one day, less than two days

假设您使用的是Java 8,那么正确的处理方法如下:

代码语言:javascript
复制
// Decide what time zone you want to work in
ZoneId tz = ZoneId.of("Europe/Berlin");

// If you wanted the local time zone of the system,
// Use this instead:
// ZoneId tz = ZoneId.systemDefault();

// Get instants from the timestamps
Instant i1 = Instant.ofEpochMilli(1466062306000l);
Instant i2 = Instant.ofEpochMilli(1466028000000l);

// Get the calendar date in the specified time zone for each value
LocalDate d1 = i1.atZone(tz).toLocalDate();
LocalDate d2 = i2.atZone(tz).toLocalDate();

// Get the difference in days
long daysBetween = ChronoUnit.DAYS.between(d2, d1);

如果您的输入是真正的Calendar对象而不是时间戳,我建议使用Calendar.toInstant(),如遗留日期-时间代码指南中所描述的那样。

如果您使用的是Java 7或更早版本,您将从Joda时间库中找到类似的功能。

如果您真的不想使用其中的任何一种,并且仍然以旧的(困难的)方式做事,那么请参阅这个例子

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

https://stackoverflow.com/questions/37869824

复制
相关文章

相似问题

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