Java XMLGregorianCalendar 格式 yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z' 的字符串日期
Java String date to XMLGregorianCalendar whit format yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'
我有一个带有日期标签的 soap 网络服务,格式如下
2019-12-01T04:00:00.0000000Z(七个零)
现在我正在实施客户端,我无法创建具有七个零的 XMLGregorianCalendar,我只剩下三个零
我的代码
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
Date date = df.parse("2019-12-01T04:00:00.0000000Z");
GregorianCalendar gcal = new GregorianCalendar();
gcal.setTime(date);
gcal.setTimeZone(TimeZone.getTimeZone("UTC"));
XMLGregorianCalendar fecha = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
System.out.println("fecha ->"+fecha.toString());
产出
fecha ->2019-12-01T07:00:00.000Z
如何让 XMLGregorianCalendar 在格式中保留七个零?
您可以使用接受数据类型的词法表示的工厂方法:
XMLGregorianCalendar fecha = DatatypeFactory.newInstance().newXMLGregorianCalendar(df.format(date));
你可能不需要 7 位小数
通常,SOAP 网络服务不需要任何特定的秒数小数位数。它需要 XML 以及 XML 格式的日期和时间。 XML 的日期和时间格式的灵感来自 ISO 8601 格式(底部的链接)。 日期和时间数据类型 上的 W3Schools 页面甚至没有提到指定秒的任何小数部分的可能性:
The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss" …
不过,允许使用小数秒,“达到任意精度”以引用 W3C 的 XML 架构第 2 部分:数据类型第二版。因此,如果您的 Web 服务坚持恰好保留 7 位小数,这是一个特殊且不寻常的限制。你可能想挑战一下。
XMLGregorianCalendar
的替代方法
XMLGregorianCalendar
class 已经老了。它完全用于为 XML 文档生成 ISO 8601 格式,与 SOAP 和许多其他地方一样。 java.time 的 classes,现代 Java 日期和时间 API,也产生 ISO 8601 格式。我们更喜欢使用这些(除非非常特殊的要求需要 XMLGregorianCalendar
)。
OffsetDateTime odt = OffsetDateTime.of(2019, 12, 1, 4, 0, 0, 0, ZoneOffset.UTC);
System.out.println(odt);
此代码段输出:
2019-12-01T04:00Z
如果您需要 7 位小数,请使用格式化程序:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSSSX");
System.out.println(odt.format(formatter));
2019-12-01T04:00:00.0000000Z
当然,如果你已经得到你的字符串,2019-12-01T04:00:00.0000000Z
,就像你的问题一样,直接把它放到你的XML文件中。如果您需要先验证它,将它传递给 Instant.parse()
并查看是否得到 DateTimeFormatException
.
如果您真的无法避免 XMLGregorianCalendar
秒数为 7 位小数的需要,有两种方法可以生成一个:
DatatypeFactory.newXMLGregorianCalendar(String)
在另一个答案中使用:
XMLGregorianCalendar fecha = DatatypeFactory.newInstance()
.newXMLGregorianCalendar("2019-12-01T04:00:00.0000000Z");
System.out.println(fecha);
2019-12-01T04:00:00.0000000Z
正在将 BigDecimal
传递给 DatatypeFactory
:
XMLGregorianCalendar fecha = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(BigInteger.valueOf(2019), 12, 1,
4, 0, 0, new BigDecimal("0.0000000"), 0);
无论如何,在任何情况下我都建议你不要使用SimpleDateFormat
和Date
。那些 classes 设计不佳且早已过时,尤其是前者是出了名的麻烦。 GregorianCalendar
也是如此。我们有时可能会将它与 XMLGregorianCalendar
一起使用,因为两者之间存在转换(如您的问题中所用)。 GregorianCalendar
只有毫秒精度,所以你永远不会通过这样的转换得到 7 位小数。
您的代码中存在错误
您的代码中有两个错误。
- 将
Z
硬编码为格式模式字符串中的文字是错误的。 Z
是与 UTC 的偏移量(零),需要这样解析,否则您将在绝大多数 JVM 上得到错误的时间。
SimpleDateFormat
也只支持毫秒,精确到秒的小数点后三位。当分数全为零时,您不会注意到错误,但一旦有人在某处输入非零数字,您就会得到错误的结果。 SimpleDateFormat
无法正确处理 2、4 或 7 个小数位。
链接
- XML Schema Part 2: Datatypes Second Edition 在 W3C 上。
- XSD Date and Time Data Types 在 W3Schools
- ISO 8601 维基百科
- Oracle tutorial: Date Time 解释如何使用 java.time.
我有一个带有日期标签的 soap 网络服务,格式如下
2019-12-01T04:00:00.0000000Z(七个零)
现在我正在实施客户端,我无法创建具有七个零的 XMLGregorianCalendar,我只剩下三个零
我的代码
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
Date date = df.parse("2019-12-01T04:00:00.0000000Z");
GregorianCalendar gcal = new GregorianCalendar();
gcal.setTime(date);
gcal.setTimeZone(TimeZone.getTimeZone("UTC"));
XMLGregorianCalendar fecha = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
System.out.println("fecha ->"+fecha.toString());
产出
fecha ->2019-12-01T07:00:00.000Z
如何让 XMLGregorianCalendar 在格式中保留七个零?
您可以使用接受数据类型的词法表示的工厂方法:
XMLGregorianCalendar fecha = DatatypeFactory.newInstance().newXMLGregorianCalendar(df.format(date));
你可能不需要 7 位小数
通常,SOAP 网络服务不需要任何特定的秒数小数位数。它需要 XML 以及 XML 格式的日期和时间。 XML 的日期和时间格式的灵感来自 ISO 8601 格式(底部的链接)。 日期和时间数据类型 上的 W3Schools 页面甚至没有提到指定秒的任何小数部分的可能性:
The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss" …
不过,允许使用小数秒,“达到任意精度”以引用 W3C 的 XML 架构第 2 部分:数据类型第二版。因此,如果您的 Web 服务坚持恰好保留 7 位小数,这是一个特殊且不寻常的限制。你可能想挑战一下。
XMLGregorianCalendar
的替代方法 XMLGregorianCalendar
class 已经老了。它完全用于为 XML 文档生成 ISO 8601 格式,与 SOAP 和许多其他地方一样。 java.time 的 classes,现代 Java 日期和时间 API,也产生 ISO 8601 格式。我们更喜欢使用这些(除非非常特殊的要求需要 XMLGregorianCalendar
)。
OffsetDateTime odt = OffsetDateTime.of(2019, 12, 1, 4, 0, 0, 0, ZoneOffset.UTC);
System.out.println(odt);
此代码段输出:
2019-12-01T04:00Z
如果您需要 7 位小数,请使用格式化程序:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSSSSSX");
System.out.println(odt.format(formatter));
2019-12-01T04:00:00.0000000Z
当然,如果你已经得到你的字符串,2019-12-01T04:00:00.0000000Z
,就像你的问题一样,直接把它放到你的XML文件中。如果您需要先验证它,将它传递给 Instant.parse()
并查看是否得到 DateTimeFormatException
.
如果您真的无法避免 XMLGregorianCalendar
秒数为 7 位小数的需要,有两种方法可以生成一个:
DatatypeFactory.newXMLGregorianCalendar(String)
在另一个答案中使用:XMLGregorianCalendar fecha = DatatypeFactory.newInstance() .newXMLGregorianCalendar("2019-12-01T04:00:00.0000000Z"); System.out.println(fecha);
2019-12-01T04:00:00.0000000Z
正在将
BigDecimal
传递给DatatypeFactory
:XMLGregorianCalendar fecha = DatatypeFactory.newInstance() .newXMLGregorianCalendar(BigInteger.valueOf(2019), 12, 1, 4, 0, 0, new BigDecimal("0.0000000"), 0);
无论如何,在任何情况下我都建议你不要使用SimpleDateFormat
和Date
。那些 classes 设计不佳且早已过时,尤其是前者是出了名的麻烦。 GregorianCalendar
也是如此。我们有时可能会将它与 XMLGregorianCalendar
一起使用,因为两者之间存在转换(如您的问题中所用)。 GregorianCalendar
只有毫秒精度,所以你永远不会通过这样的转换得到 7 位小数。
您的代码中存在错误
您的代码中有两个错误。
- 将
Z
硬编码为格式模式字符串中的文字是错误的。Z
是与 UTC 的偏移量(零),需要这样解析,否则您将在绝大多数 JVM 上得到错误的时间。 SimpleDateFormat
也只支持毫秒,精确到秒的小数点后三位。当分数全为零时,您不会注意到错误,但一旦有人在某处输入非零数字,您就会得到错误的结果。SimpleDateFormat
无法正确处理 2、4 或 7 个小数位。
链接
- XML Schema Part 2: Datatypes Second Edition 在 W3C 上。
- XSD Date and Time Data Types 在 W3Schools
- ISO 8601 维基百科
- Oracle tutorial: Date Time 解释如何使用 java.time.