【问题标题】:Format LocalDateTime to XMLGregorianCalender with offset将 LocalDateTime 格式化为带偏移量的 XMLGregorianCalender
【发布时间】:2020-06-17 10:17:58
【问题描述】:

我有一个 LocalDateTime 的实例。

我需要将它映射到 XMLGregorianCalendar(在此处使用 JAXB),最后是 XML,我希望时间在 XML 文档中如下所示: 2020-03-04T19:45:00.000 + 1:00(1 小时是与 UTC 的偏移量)。

我尝试使用 DateTimeFormatter 将 LocalDateTime 转换为字符串,然后将其映射到 XMLGregorianCalender。

我现在有两个问题:

  1. 我无法在 DateTimeFormatter 中找到任何格式化程序 哪个格式的时间偏移到 UTC?做这样的事情 存在还是我需要定义我的格式化程序模式?

    其次,如果我能够将 LocalDateTime 格式化为字符串格式,我 需要,如果我只是创建一个 XMLGregorianCalendar 从 字符串表示?

【问题讨论】:

标签: java xml datetime-format xmlgregoriancalendar


【解决方案1】:

如果要从JVM的默认时区导出时区偏移量,那么编码如下:

LocalDateTime localDateTime = LocalDateTime.now();
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()); // <== default
OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
        .newXMLGregorianCalendar(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));

System.out.println(localDateTime);        // 2020-03-04T15:58:09.604171800
System.out.println(zonedDateTime);        // 2020-03-04T15:58:09.604171800-05:00[America/New_York]
System.out.println(offsetDateTime);       // 2020-03-04T15:58:09.604171800-05:00
System.out.println(xmlGregorianCalendar); // 2020-03-04T15:58:09.604171800-05:00

如果你想硬编码+01:00 的偏移量,那么可以这样操作:

LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(1)); // <== hardcoded
XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
        .newXMLGregorianCalendar(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));

System.out.println(localDateTime);        // 2020-03-04T16:00:04.437550500
System.out.println(offsetDateTime);       // 2020-03-04T16:00:04.437550500+01:00
System.out.println(xmlGregorianCalendar); // 2020-03-04T16:00:04.437550500+01:00

或者像这样:

LocalDateTime localDateTime = LocalDateTime.now();
XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance()
        .newXMLGregorianCalendar(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
xmlGregorianCalendar.setTimezone(60); // <== hardcoded

System.out.println(localDateTime);        // 2020-03-04T16:03:09.032191
System.out.println(xmlGregorianCalendar); // 2020-03-04T16:03:09.032191+01:00

【讨论】:

  • 这似乎有效。在某些情况下,我会创建没有秒数的 LocalDateTime 对象或将其设置为零秒,在这种情况下,xmlgregoriancalendar 会引发异常。重现异常的示例代码:LocalDateTime paymentStatusTime = LocalDateTime.of(2020, 1, 1, 9, 30, 0); ZonedDateTime gmtTime = ZonedDateTime.of(localDateTime, ZoneId.of("CET")); OffsetDateTime offsetDateTime = gmtTime.toOffsetDateTime(); System.out.println("偏移时间为" + offsetDateTime); return DatatypeFactory.newInstance().newXMLGregorianCalendar(offsetDateTime.toString());
  • @Nitesh 将 offsetDateTime.toString() 替换为 offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
  • 谢谢,我自己也试过了,确实有效
  • @Nitesh 这不是奇怪的行为,Z 的使用对于dateTime XML 模式数据类型是明确定义的,因此任何 XML 解析器都应该支持它,并且它是规范XMLGregorianCalendar坚持。 --- Z 也在ISO 8601 中指定,这是 XML 模式定义格式的基础。 --- 虽然+00:00dateTimelexical 表示允许,但canonical 表示指定Z 必须用于零偏移。跨度>
  • @Nitesh 如果有人不支持Z 时区指定,那么他们 没有遵循 XML 模式标准/ISO-8601 规范。 为他们感到羞耻! --- 而不是“自定义类型”,为什么不直接使用 OffsetDateTime 和不会使用 ZDateTimeFormatter 作为偏移量?例如。如果你只需要毫秒精度,uuuu-MM-dd'T'HH:mm:ss.SSSxxx 模式就可以了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 2019-12-24
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
相关资源
最近更新 更多