繁体   English   中英

Java中可以使用什么日期时间格式来处理夏令时

[英]What Date time format can be used to handle DST in Java

我们的客户在文本文件中以以下格式的字符串向我们发送开始和结束日期时间

2019-10-07 11:07 上午

所有日期时间都在一个时区。 我们计算开始和结束日期时间之间的差异来计算工作时间。 当夏令时转换发生时,工作时间计算出错。 他们没有发送足够的信息供我们正确计算。

我将建议他们向我们发送更多信息,以便我们解决此问题。 这里有什么好的解决方案? 我们应该向他们推荐哪种日期时间格式,以帮助我们解决 DST 更改并正确计算工作时间。

我们使用 Java。

做对并不明显

他们告诉你他们的当地时间,你可以推断出时区(因为“所有日期都在一个时区”)。

基本计算如下所示:

ZoneId pacific = ZoneId.of("America/Los_Angeles");
DateTimeFormatter local = DateTimeFormatter.ofPattern("uuuu-MM-dd hh:mm a").withZone(pacific);
ZonedDateTime start = ZonedDateTime.parse("2022-11-06 01:30 AM", local);
ZonedDateTime until = ZonedDateTime.parse("2022-11-07 01:30 AM", local);
long hours = start.until(until, ChronoUnit.HOURS);
System.out.printf("%d hours elapsed%n", hours);

这将打印“已过去25 小时”。 在太平洋时区,2022 年 11 月 6 日是 25 小时,因为秋季夏令时结束时,时钟会拨慢一小时。 如果有人告诉您现在是凌晨 1:00,您不知道午夜是一小时前还是两小时前。

默认偏移试探法

您真正需要的是偏移量,为此您必须依赖一些启发式方法。 默认情况下, ZonedDateTime 通过选择最早的偏移量(“夏季”偏移量)从多个不明确的本地日期时间中选择一个时刻。

指定偏移量

如果这不是您想要的,您可以显式覆盖偏移量。 例如,也许你接近实时地处理这些时间戳,你可以根据当前时间猜出偏移量应该是多少。 或者您可能知道这些本地时间戳总是按时间顺序处理; 通过跟踪您看到的最晚时间,并注意后面是否有更早的时间戳,您可以检测到时钟拨回并更改偏移量。

ZonedDateTime.ofLocal()ZonedDateTime.ofStrict()函数可用于显式控制偏移量。

偏移日期时间

或者,您可能会要求他们在时间戳字符串中包含偏移量。 通常这会用带符号的小时数和分钟数表示:“-07:00”或“-0800”。 这将在 DST 转换期间提供明确的时间解释。


这是使用OffsetDateTime的示例。 首先,如果偏移量使用冒号,如“2019-10-07T11:07:00+01:00”,这是一种标准格式,可以这样解析:

OffsetDateTime start = OffsetDateTime.parse("2019-10-07T11:07:00+01:00");

如果缺少冒号,则需要格式化程序来处理非标准输入:

DateTimeFormatter odt = new DateTimeFormatterBuilder()
    .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
    .appendOffsetId()
    .toFormatter();
OffsetDateTime when = OffsetDateTime.parse("2019-10-07T11:07:00+01:00", odt);

从那里开始,计算与ZonedDateTime相同:

OffsetDateTime start = OffsetDateTime.parse("2022-11-06T01:00:00-07:00", odt);
OffsetDateTime until = OffsetDateTime.parse("2022-11-07T01:54:00-08:00", odt);
long hours = start.until(until, ChronoUnit.HOURS);
System.out.printf("%d complete hours elapsed.%n", hours);
Duration duration = Duration.between(start, until);
System.out.println("Full duration: " + duration);

这是一个简单的任务。 DateTimeFormatter class 为您提供所需的所有信息。 2019-10-07 11:07 AM 您的格式为'yyyy-MM-dd hh:mm a' ,您应该使用LocalDateTime class。但是由于您需要考虑夏令时,因此您可能需要使用类ZonedDateTimeOffsetDateTime并提供您的时区。 这可能有点矫枉过正,但我曾经参与过一个项目,我需要在事先不知道格式的情况下将字符串解析为日期。 所以,这是我写的关于如何做到这一点的文章: Java 8 java.time package:解析任何字符串到日期

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM