将时间重置为午夜减去一天

时间:2014-08-18 19:29:15

标签: java date calendar

我有以下代码,它应该将给定时间(以毫秒为单位)重置为同一天的午夜。我有两个时间实例,1409097600000l和1409270400000l,两者都已经在午夜。但是,在通过重置代码后,一个未触及,而另一个在前一天结束(-86400000)。我想知道是否有人可以解释发生了什么。这是我的代码:

Calendar start = Calendar.getInstance();
start.setTimeZone(TimeZone.getTimeZone("UTC"));
start.setTime(new Date(1409097600000l));
// reset hour, minutes, seconds and millis
start.set(Calendar.HOUR_OF_DAY, 0);
start.set(Calendar.MINUTE, 0);
start.set(Calendar.SECOND, 0);
start.set(Calendar.MILLISECOND, 0);

System.out.println("All Day Start: " + start.getTimeInMillis());

Calendar end = Calendar.getInstance();
end.setTime(new Date(1409270400000l));
System.out.println("1: " + end.getTimeInMillis());
end.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("2: " + end.getTimeInMillis());
// reset hour, minutes, seconds and millis
end.set(Calendar.HOUR_OF_DAY, 0);
end.set(Calendar.MINUTE, 0);
end.set(Calendar.SECOND, 0);
end.set(Calendar.MILLISECOND, 0);
System.out.println("All Day End: " + (end.getTimeInMillis()));

我机器上的输出是:

All Day Start: 1409097600000
1: 1409270400000
2: 1409270400000
All Day End: 1409184000000

2 个答案:

答案 0 :(得分:3)

您需要在设置时间后设置第二个日历的时区。所以你要在默认时区设置时间(可能是你当地的时间)。然后你改变时区,这显然是昨天的某个时间。

向上移动第二个实例中的setTimeZone行,就像您在第一个实例中一样。

答案 1 :(得分:1)

接受的答案是正确的。但是你有其他问题。

旧的捆绑类java.util.Date和.Calendar非常麻烦。避免他们。他们真的那么糟糕。而是使用古老的Joda-Time库或现在与Java 8捆绑在一起的新java.time包(受Joda-Time启发)。

您的代码假定当天的第一个时刻是午夜,这意味着00:00:00。由于夏令时或其他异常情况,并非总是如此。对于UTC,它始终是真的,被授予。不过,我建议养成在Joda-Time中调用withTimeAtStartOfDay方法的习惯。

提示:在L字面值中使用大写long而不是小写字母可以避免与数字1混淆。

Joda-Time提供了三个类来处理一段时间,例如你在这个问题:Interval,Period和Duration。

这项工作在Joda-Time中更简单。

long startLong = 1409097600000L;
long stopLong = 1409270400000L;
DateTime start = new DateTime( startLong , DateTimeZone.UTC );
DateTime start2 = start.withTimeAtStartOfDay();
DateTime stop = new DateTime( stopLong , DateTimeZone.UTC );
DateTime stop2 = stop.withTimeAtStartOfDay();
Interval interval = new Interval( start2 , stop2 );