ZonedDateTime 忽略 ss 部分的 00

ZonedDateTime ignores 00 for ss part

我正在尝试转换字符串值“2018-10-11T12:00:00Z”;到 ZonedDateTime。 如果我使用默认 ZonedDateTime.parse(zonedDateTime) 然后 ss 部分即 00 被删除,我得到“2018-10-11T12:00Z”作为输出。

请问如何将 00 保留为 SS 部分。

String zonedDateTime = "2018-10-11T12:00:00Z";

ZonedDateTime z =  ZonedDateTime.parse(zonedDateTime);
System.out.println(z);  // return 2018-10-11T12:00Z

ZonedDateTime z1 =  ZonedDateTime.parse (zonedDateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ") );

System.out.println(z1);  // Exception : Text '2018-10-11T12:00:00Z' could not be parsed at index 19

打印秒数

当您使用 System.out.println 打印 ZonedDateTime 时,您隐含地调用了它的 toString 方法。当秒和秒的小数部分为 0 时,toString 将它们排除在外。无论如何要打印它们,请使用格式化程序进行格式化(而不是使用一个进行解析):

    DateTimeFormatter formatterWithSeconds = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX");
    System.out.println("z with seconds: " + z.format(formatterWithSeconds));

输出为:

z with seconds: 2018-10-11T12:00:00Z

此处的重要区别在于 ZonedDateTime 对象及其字符串表示形式。 ZonedDateTime对象 always 包含秒和纳秒,当它们为 0 时也是如此。字符串表示可能包含也可能不包含它们。一个参数 ZonedDateTime.parse 已解析 00 秒。顺便说一句,它接受带秒和不带秒的字符串。

使用 Instant 或 OffsetDateTime

顺便说一句,由于您的字符串包含偏移量 (Z) 并且没有时区(如 Africa/Nairobi),因此 OffsetDateTime 匹配更精确地表示。如果您始终 search/replace ZonedDateTimeOffsetDateTime 代码将正常工作,因为 API 相似。

如果偏移量始终为 Z(对于“祖鲁时区”或 UTC 的偏移量 0),请使用 Instant:

    String instantString = "2018-10-11T12:00:00Z";
    Instant i = Instant.parse(instantString);
    System.out.println("As Instant: " + i);

我已经为您的 String 变量取了一个更适合此代码段的名称;它仍然是相同的字符串。输出:

As Instant: 2018-10-11T12:00:00Z

奇怪的是 Instant.toString 即使秒数为 0 也会打印出来。

请阅读@Basil Bourque 的回答中有关正确类型的更多信息。

你的代码出了什么问题?用于解析 Z

的模式字母
// Exception : Text '2018-10-11T12:00:00Z' could not be parsed at index 19

这里的问题不在于秒数,也不在于 ss。索引 19 是 Z 在您的字符串中的位置。双参数 ZonedDateTime.parse 反对,因为模式字母 Z 与日期时间字符串中的 Z 不匹配。如果您确实需要提供用于解析 Z 的格式模式字符串,请使用大写字母 X(其中一个或多个取决于非零偏移量的外观)。来自模式字母的文档:

  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00

链接

是正确的,应该接受。我将添加一个想法和一个方便的参考 table.

Instant

我想强调另一个答案中提出的观点,即 ZonedDateTime 在技术上可行但不是最合适的 class 来解析诸如 2018-10-11T12:00:00Z 的字符串。此格式在 ISO 8601 标准中定义。最后的 Z 发音为“Zulu”,表示 UTC(零时-分-秒的偏移量)。

ISO 8601 标准格式在 java.time class 中默认使用。无需指定格式化模式。

Instant 是合适的 class 来表示 UTC 中的时刻。

Instant instant = Instant.parse( "2018-10-11T12:00:00Z" ) ;

以相同的 ISO 8601 标准格式生成字符串。

String output = instant.toString() ;

OffsetDateTime class 表示 UTC 中的时刻或其他与 UTC 的偏移量值,任意小时-分钟-秒。这个 class 也更灵活,例如通过 DateTimeFormatter class 生成各种格式的字符串。并且 class 需要 JDBC 4.2 及更高版本的驱动程序支持,而 InstantZonedDateTime 支持在 JDBC 中是可选的。

弄清楚时差和时区的区别。

  • Offset-from-UTC
    简单的小时-分钟-秒数。领先于 UTC(向东)为正,落后于 UTC(向西)为负。
  • Time zone
    一个时区。时区是特定地区的人们使用的偏移量的过去、现在和未来变化的历史。

Java

中的日期时间类型

这里是 Java 中基本日期时间数据类型的参考 table,包括现代的和传统的。避免遗留类型:它们很糟糕,由不了解日期时间处理的复杂性和微妙性的人设计。