TimeUnit类是否损坏?

威利·曼策尔(Willi Mentzel)

我注意到TimeUnit类的奇怪行为,因此我创建了这个最小的示例来重现它。

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

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

是一个以毫秒为单位的日期计算器供您检查。

马特·约翰逊·品特

您可以通过简单的数学更好地了解这里发生的事情:

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,如下所示:

// 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 Time库中找到类似的功能

如果您真的不想使用其中任何一个,并且仍然以旧的(硬性)方式进行操作,那么请参见此示例

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章