如何从给定的瞬间获得两个午夜? [英] How can I get two midnights from given instant?
问题描述
我需要计算今天的00:00 AM和明天的00:00 AM。
I need to calculate 00:00 AM of today and 00:00 AM of tomorrow.
我想尝试这样
private static void some(final Date now) {
final Calendar calendar = Calendar.getInstance();
calendar.setTime(now);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
final Date min = calendar.getTime(); // 00:00 AM of today
calendar.add(Calendar.DATE, 1);
final Date max = calendar.getTime(); // 00:00 AM of tomorrow
}
是否有更好的)
推荐答案
有什么问题需要解决。
首先,today对于 Date
不是一个明确定义的概念。 Date
基本上只是一个包装器自从Unix纪元以来的毫秒数:对应于该时刻的日历日期是不同的,取决于你在哪个时区。
Firstly, "today" is not a well-defined concept for a Date
. Date
is basically just a wrapper around number of milliseconds since Unix epoch: the calendar date corresponding to that instant is different, depending upon which timezone you are in.
例如,新日期(1469584693000)
代表的时间在2016-07-27在伦敦;但它是在纽约市的2016-07-26。
For instance, the instant represented by new Date(1469584693000)
was on 2016-07-27 in London; but it was on 2016-07-26 in NYC.
当然,你可以依赖于JVM的默认时区,但这使得代码的行为依赖JVM的配置。
You can, of course, rely upon the JVM's default timezone, but this makes the behaviour of the code dependent upon the JVM's configuration.
其次,午夜不是总是存在的:eg在亚洲/加沙
时区,夏令时从午夜开始,意味着时钟从一天的23:59:59跳到下一个的01:00:00请参阅 Ideone演示 )。这就是为什么Java 8时间API具有 atStartOfDay
,而不是 atMidnight
。
Secondly, "midnight" isn't something that always exists: e.g. in the Asia/Gaza
timezone, daylight savings starts at midnight, meaning that the clock jumps from 23:59:59 on one day to 01:00:00 on the next (see Ideone demo). This is why the Java 8 time API has methods called atStartOfDay
, not atMidnight
.
所以,你可以把这在一起,在Java 8,到:
So, you can put this together, in Java 8, to:
private static void some(final Date now, ZoneId zone) {
Instant instant = now.toInstant(); // Convert from old legacy class to modern java.time class.
ZonedDateTime zdt = instant.atZone(zone); // Apply a time zone to the UTC value.
LocalDate today = zdt.toLocalDate(); // Extract a date-only value, without time-of-day and without time zone.
ZonedDateTime startOfDayToday = today.atStartOfDay(zone); // Determine first moment of the day.
ZonedDateTime startOfDayTomorrow = today.plusDays(1).atStartOfDay(zone);
// ...
}
您可以直接将即时
或 ZonedDateTime
传递给方法;您可以使用显式常量 ZoneId
,例如 ZoneId.of(UTC)
。
Of course, you can directly pass in the Instant
or ZonedDateTime
to the method; and you can use an explicit constant ZoneId
, e.g. ZoneId.of("UTC")
.
这篇关于如何从给定的瞬间获得两个午夜?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!