ZonedDateTime toString 符合 ISO 8601

2022-09-01 22:20:00

我正在尝试确保调用我的对象符合 ISO-8601 格式。toString()ZonedDateTime

该方法的文档指出:toString()

...如果偏移和 ID 相同,则输出与 ISO-8601 兼容

这是否意味着存在调用将返回与 不同内容的情况?zdt.getOffset()zdt.getZone().getRules().getOffset(zdt.toInstant())

这似乎没有道理。

有人可以提供一个偏移量和ID不相同的示例(即:不符合ISO-8601的地方),以便我可以更好地理解文档中的描述。toString()


答案 1

这是完整的规范:

 * Outputs this date-time as a {@code String}, such as
 * {@code 2007-12-03T10:15:30+01:00[Europe/Paris]}.
 * <p>
 * The format consists of the {@code LocalDateTime} followed by the {@code ZoneOffset}.
 * If the {@code ZoneId} is not the same as the offset, then the ID is output.
 * The output is compatible with ISO-8601 if the offset and ID are the same.

Javadoc 规范是指 用 a 而不是 named 构造的情况,因此偏移量和 ID 是相同的:ZonedDateTimeZoneOffsetZoneId

System.out.println(ZonedDateTime.now(ZoneId.of("Europe/Paris")));
// 2017-04-26T15:13:12.006+02:00[Europe/Paris]

System.out.println(ZonedDateTime.now(ZoneOffset.ofHours(2)));
// 2017-04-26T15:13:12.016+02:00

可以看出,在第二种情况下,使用 a 时,格式省略了末尾的方括号部分。通过省略该部分,结果是ISO-8601兼容。ZoneOffsettoString()

boolean iso8601Compatible = zdt.getZone() instanceof ZoneOffset;

为了保证ISO-8601兼容输出的使用:toOffsetDateTime()

String isoCompatible = zdt.toOffsetDateTime().toString();

或格式化程序。


答案 2

文档中的示例是 。这恰好不符合ISO标准,因为ISO-8601不包括该部件。这是开发人员在尽可能接近标准和仍然以明确的方式证明时区信息之间做出的折衷。2007-12-03T10:15:30+01:00[Europe/Paris][Europe/Paris]java.time

因此,真正的问题实际上可能恰恰相反:如果包含ISO不包括的时区信息,那么结果何时完全符合ISO标准?“如果偏移量和 ID 相同”是什么意思?在这里,我们必须记住,它是 的子类,可以用作 中的区域 ID。在本例中,偏移量和 ID 是相同的。否则,他们不是。对于特定示例,可能会产生 。这是完全ISO兼容的,因为区域被给出为 just ,这与偏移量相同。还以格式给出了一些东西。由于算作偏移量,因此这也是兼容的。ZonedDateTime.toString()ZoneOffsetZoneIDZonedDateTimeZonedDateTime.now(ZoneOffset.ofHours(+2)).toString()2017-04-26T15:04:59.828+02:00+02:00ZonedDateTime.now(ZoneOffset.UTC).toString()2017-04-26T13:04:59.828ZZ

我认为在大多数情况下,它不会很有用。如果你的区域只是一个偏移量,你通常更喜欢使用 over ,如果是这样,你当然不在乎是否与 ISO 兼容。OffsetDateTimeZonedDateTimeZonedDateTime.toString()


推荐