Java 解析时间戳的差异被忽略

Java differences in parsed timestamps are ignored

在以下示例中,我成功地解析了格式为 yyMMddHHmmss(+-)HHss(日期加上或减去一些时间偏移)的时间戳。

所以,当我给出两个相同的时间戳和一个不同的班次时,结果应该是不同的。

例如,我们取日期时间:190219010000(2019 年 2 月 19 日,01:00 [AM]),我们可以增加 2 小时(时间将为 03:00)或减去 2 小时(时间为 23:00,日期为 2 月 18 日)——也就是说,解析后的对象应该有 4 小时的差异。

在下面的 运行 示例中,时移被忽略。我可以写任何数字,输出总是“2019 年 2 月 19 日,01:00”。

//Input timestamps: "190219010000+0200" "190219010000-0200"
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class HelloWorld
{
  public static void main(String[] args)
  { //parsing "19th of February 2019, 01:00 [AM]" +- 2hours
    LocalDateTime ldt1 = LocalDateTime.parse("190219010000+0200", DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
    LocalDateTime ldt2 = LocalDateTime.parse("190219010000-0200", DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
    System.out.println("190219010000+0200: " +ldt1);
    System.out.println("190219010000-0200: "+ ldt2);
  }
}

真实输出:两种情况下输出相同,但输入不同:/

190219010000+0200: 2019-02-19T01:00
190219010000-0200: 2019-02-19T01:00

预期输出:

190219010000+0200: 2019-02-19T03:00
190219010000-0200: 2019-02-18T23:00

也许我应该用别的东西代替模式中的 x?或者 LocalDateTimeFormatter(不存在)而不是 DateTimeFormatter?

谢谢

In the following, running example, the timeshift is ignored.

是的,这并不让我感到惊讶。您正在解析所表示的 local 值 - 这就是 LocalDateTime.

的含义

一串“190219010000+0200”表示"February 19th 2019, 1am local time, with a UTC offset of 2 hours"。那个的当地时间是2019-02-19T01:00。如果您不想获取由您的文本表示的本地日期和时间,LocalDateTime 是错误的类型。

看起来您 真正 想要的是 UTC 时间,在这种情况下,您应该将值解析为 OffsetDateTime,然后可能转换为 Instant。不过,我希望结果与您相反:+0200 通常表示 "the local time is two hours ahead of UTC",使前一天晚上 11 点的 UTC 值成为 - 这不是添加到 get[= 的数量26=] 到 UTC。

LocalDateTime 没有时区信息,也不存储或表示时区。因此,在您的情况下, ldt1ldt2 都代表相同的本地时间。

别人说的,你误会了。在您的代码中,LocalDateTime.parse 的行为符合设计。

你是对的,190219010000+0200 是一个明确的时间点(假设我们知道格式是 yyMMddHHmmssx)。 LocalDateTime.parse 为您提供字符串中的本地日期和时间。换句话说,偏移量 +02:00 处的本地日期和时间。

如果您想要转换,例如转换为 UTC,您需要明确指定:

    OffsetDateTime odt1 = OffsetDateTime.parse("190219010000+0200", 
            DateTimeFormatter.ofPattern("yyMMddHHmmssx"));
    LocalDateTime ldt1 = odt1.withOffsetSameInstant(ZoneOffset.UTC)
            .toLocalDateTime();

    System.out.println("190219010000+0200: " + ldt1);

现在输出是你所期望的。差不多。

190219010000+0200: 2019-02-18T23:00

正如 Jon Skeet 已经说过的那样 +0200 通常意味着 +02:00 的 UTC 偏移已被 应用于日期和时间。所以 01:00 在 +02:00 与 UTC 前一天的 23:00 是同一时间点(如果你的字符串非常特殊并且应用相反的偏移约定,那也可以解决,但需要更多的手工作业)。