流行测验:这个小程序的输出是什么?
public class DateFun {public static void main(String[] args) {long hours = getHoursOfDay(LocalDate.now(), ZoneId.systemDefault());System.out.println(hours);}private static long getHoursOfDay(LocalDate date, ZoneId zoneId) {ZonedDateTime startOfDay = date.atStartOfDay(zoneId);Duration duration = Duration.between(startOfDay, startOfDay.plusDays(1));return duration.toHours();}
}
就像最有趣的问题一样,答案是“取决于”。 它如何依赖? 好吧,让我们尝试一些例子:
-
getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Asia/Colombo"))
返回24
。 符合预期 -
getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Europe/Oslo"))
也返回24
。 - 但这是一个有趣的版本:
getHoursOfDay(LocalDate.of(2014, 3, 30), ZoneId.of("Europe/Oslo"))
返回23
! 这是夏令时。 - 同样:
getHoursOfDay(LocalDate.of(2014, 10, 26), ZoneId.of("Europe/Oslo"))
也返回25
- 当然,下面一切都颠倒了:
getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Melbourne"))
得出23。 - 当然,除了昆士兰州:
getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Queensland"))
=> 24。
夏时制:程序员的祸根!
实行夏令时的目的是通过提供更多的带灯工作时间来提高工人的生产率。 许多研究未能证明它可以按预期工作。
取而代之的是,当我检查挪威的夏令时的历史时,发现它是由高尔夫球手和蝴蝶收藏家(“鳞翅目动物”)游说的,以便他们在下班后能更好地追求自己的爱好。 因此,此博客文章的名称。
大多数时候,您可以忽略夏令时。 但是,当您无法做到这一点时,它确实可以将您咬在背后。 例如:从夏令时更改为标准时间的那一天,电源计划的每小时生产看起来是什么样的? 同事给我的另一个例子:电视时间表。 事实证明,在秋天的额外一小时内,有些电视频道根本就不愿意显示节目。 否则他们将显示同一小时的编程两次。
Joda-Time API和现在的Java 8 time API java.time可以提供帮助。 如果正确使用。 这是显示每小时值表的代码:
void displayHourlyTable(LocalDate date, ZoneId zoneId) {ZonedDateTime startOfDay = date.atStartOfDay(zoneId);ZonedDateTime end = startOfDay.plusDays(1);for (ZonedDateTime current = startOfDay; current.isBefore(end); current = current.plusHours(1)) {System.out.println(current.toLocalTime() + ": " + current.toInstant());}
}
鉴于2014/10/26和奥斯陆,此打印:
00:00: 2014-10-25T22:00:00Z
01:00: 2014-10-25T23:00:00Z
02:00: 2014-10-26T00:00:00Z
02:00: 2014-10-26T01:00:00Z
03:00: 2014-10-26T02:00:00Z
....
并在2014/3/30上打印:
00:00: 2014-03-29T23:00:00Z
01:00: 2014-03-30T00:00:00Z
03:00: 2014-03-30T01:00:00Z
04:00: 2014-03-30T02:00:00Z
....
因此,如果您发现自己正在编写这样的代码: for (int hour=0; hour<24; hour++) doSomething(midnight.plusHours(hour));
您可能要重新考虑! 该代码每年(可能)会中断两次。
从表面上看,时间是一个简单的概念。 当您开始研究细节时,有一个原因java.time库包含20个类(如果不计算子包的话)。 正确使用时,时间计算很简单。 如果使用不当,时间计算看起来很简单,但包含一些细微的错误。
下次,也许我应该仔细考虑周数的一些要点。
翻译自: https://www.javacodegeeks.com/2014/08/the-lepidopterists-curse-playing-with-java-time.html