XMLGregorianCalendar日期格式' dd / MM / yyyy HH:mm:ss.SSS'

时间:2017-08-23 07:59:35

标签: java xml date

String formatA ="yyyy-MM-dd'T'HH:mm:ss'Z'";
String formatB = "dd/MM/yyyy HH:mm:ss.SSS";
try {
    XMLGregorianCalendar gregFmt = DatatypeFactory.newInstance().newXMLGregorianCalendar(new SimpleDateFormat(formatB).format(new Date()));
    System.out.println(gregFmt);
} catch (DatatypeConfigurationException e) {
};

我正在尝试格式化XMLGregorianCalendar日期。 上述代码格式适用于格式"yyyy-MM-dd'T'HH:mm:ss'Z'"

但是对于formatB dd/MM/yyyy HH:mm:ss.SSS,它会抛出错误

java.lang.IllegalArgumentException

就如何解决问题提出建议。非常感谢你!

日志

Exception in thread "main" java.lang.IllegalArgumentException: 23/08/2017 16:13:04.140
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseAndSetYear(XMLGregorianCalendarImpl.java:2887)
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2773)
at com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:435)
at com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:536)
at test.test.main(test.java:19)

第19行是第4行,在上面的代码&#39; XMLGregorianCalendar gregFmt ...&#39;

2 个答案:

答案 0 :(得分:2)

newXMLGregorianCalendar(string)接受的格式在the XML specs中有所描述,与您尝试使用的formatB不同。

答案 1 :(得分:-1)

tl; dr

  • 日期对象没有“格式”。它们解析并生成String对象,以文本形式表示其值。
  • 使用现代的 java.time 代替了可怕的旧类DateXMLGregorianCalendar类。

示例:

myXMLGregorianCalendar   // If you must use this class… but try to avoid. Use *java.time* classes instead.
.toGregorianCalendar()   // Converting from `javax.xml.datatype.XMLGregorianCalendar` to `java.util.GregorianCalendar`.
.toZonedDateTime()       // Converting from `java.util.GregorianCalendar` to `java.time.ZonedDateTime`, from legacy class to modern class.
.format(                 // Generate a `String` representing the moment stored in our `ZonedDateTime` object.
    DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss.SSS" )  // Define a formatting pattern as you desire. Or better, automatically localize by calling `DateTimeFormatter.ofLocalized…` methods.
)                        // Returns a `String` object, distinct from our `ZonedDateTime` object.
  

2018/07/07 15:20:14.372

日期对象没有格式

请勿将日期时间对象与它们生成的代表其值的字符串进行混淆。日期时间值(包括以下讨论的类)不是String,不使用文本作为其内部值,也没有“格式”。它们都可以生成并解析字符串以表示其日期时间值。

java.time

现代方法使用 java.time 类代替了麻烦的旧的传统日期时间类,例如XMLGregorianCalendar

java.util.Date的使用应替换为java.time.Instant。两者都代表UTC的时刻。 Instant使用的是纳秒级而非毫秒级的更精细分辨率。

您可以轻松地在现代类和传统类之间进行转换。注意在旧类中添加了新的转换方法,在这种情况下为java.util.GregorianCalendar::toZonedDateTime

首先从javax.xml.datatype.XMLGregorianCalendar转换为java.util.GregorianCalendar

GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;

现在摆脱这些遗留类,进入java.time。

ZonedDateTime zdt = gc.toZonedDateTime() ;

到目前为止,XMLGregorianCalendarGregorianCalendarZonedDateTime的所有三种类型都表示同一时刻,带日期的日期和指定的时区。

使用ZonedDateTime,您可以生成标准ISO 8601格式的字符串,扩展为将时区的名称附加在方括号中。

String output = zdt.toString() ;  // Generate string in standard ISO 8601 format extended by appending the name of time zone in square brackets.
  

2018-07-07T15:20:14.372-07:00 [美国/洛杉矶]

您可以使用DateTimeFormatter类生成其他格式的字符串。对于问题中第二个列出的格式设置模式,请定义一个匹配的DateTimeFormatter对象。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss.SSS" ) ;
String output = zdt.format( f ) ;
  

2018/07/07 15:20:14.372

问题中列出的第一个格式设置模式的末尾带有Z,表示UTC,发音为“ Zulu”。要将我们的ZonedDateTime调整为UTC,只需提取一个Instant对象。根据定义,Instant始终使用UTC。

Instant instant = zdt.toInstant() ;  // Extract an `Instant` object, always in UTC.

以“问题”开头显示的模式生成字符串。

String output = instant.toString() ;  // Generate string in standard ISO 8601 format.
  

2018-07-07T22:20:14.372Z


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore