将Java Date转换为XML Date Format(反之亦然)

有没有一种简单的方法将Java Date转换为XML日期字符串格式,反之亦然?

干杯,

Andez

原始答案

我在这里猜测,“XML日期格式”你的意思是“2010-11-04T19:14Z”。 它实际上是ISO 8601格式。

您可以使用SimpleDateFormat转换它,正如其他人建议的那样,FastDateFormat或使用Joda Time ,我认为这是为此目的特别创建的。

编辑:代码示例等

正如在评论中所说的那样,这个答案可以用例子来改进。

首先,我们必须明确原来的答案已经过时了。 这是因为Java 8引入了操作日期和时间的类 – java.time包应该是有意义的。 如果您有幸使用Java 8,则应使用其中之一。 然而,这些事情令人惊讶地难以做到。

LocalDate(时间)不是

考虑这个例子:

 LocalDateTime dateTime = LocalDateTime.parse("2016-03-23T18:21"); System.out.println(dateTime); // 2016-03-23T18:21 

起初看起来我们在这里使用的是本地(对用户日期和时间)。 但是,如果你敢问,你会得到不同的结果:

 System.out.println(dateTime.getChronology()); // ISO 

这实际上是ISO时间。 我认为它应该是’UTC’,但是它没有当地时区的概念。 所以我们应该认为它是普遍的。
请注意,我们正在解析的字符串末尾没有“Z”。 如果你添加日期和时间的任何东西,你会受到java.time.format.DateTimeParseException 。 因此,如果我们想要解析ISO8601字符串,似乎这个类没用。

ZonedDateTime来救援

幸运的是,有一个类允许解析ISO8601字符串 – 它是一个java.time.ZonedDateTime 。

 ZonedDateTime zonedDateTime = ZonedDateTime.parse("2016-03-23T18:21+01:00"); System.out.println(zonedDateTime); // 2016-03-23T18:21+01:00 ZonedDateTime zonedDateTimeZulu = ZonedDateTime.parse("2016-03-23T18:21Z"); System.out.println(zonedDateTimeZulu); // 2016-03-23T18:21Z 

这里唯一的问题是,你实际上需要使用时区指定。 尝试解析原始日期时间(即“2016-03-23T18:21”)将导致已经提到的RuntimeException 。 根据情况,您必须在LocalDateTimeZonedDateTime之间进行选择。
当然你可以很容易地在这两者之间进行转换,所以它不应该是一个问题:

 System.out.println(zonedDateTimeZulu.toLocalDateTime()); // 2016-03-23T18:21 // Zone conversion ZonedDateTime cetDateTime = zonedDateTimeZulu.toLocalDateTime() .atZone(ZoneId.of("CET")); System.out.println(cetDateTime); // 2016-03-23T18:21+01:00[CET] 

我建议现在使用这些课程。 但是,如果您的职位描述包括考古学(意味着您没有幸运地使用超过2年的Java 8 …),您可能需要使用其他东西。

SimpleDateFormat的乐趣

我不是https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html的忠实粉丝,但有时你别无选择。 问题是,它不是线程安全的,如果不喜欢的话,它会在你的脸上抛出一个检查过的Exception (即ParseException )。 因此代码片段相当丑陋:

 private Object lock = new Object(); // ... try { synchronized (lock) { // Either "2016-03-23T18:21+01:00" or "2016-03-23T18:21Z" // will be correctly parsed (mind the different meaning though) Date date = dateFormat.parse("2016-03-23T18:21Z"); System.out.println(date); // Wed Mar 23 19:21:00 CET 2016 } } catch (ParseException e) { LOG.error("Date time parsing exception", e); } 

FastDateFormat

FastDateFormat是同步的,因此您至少可以摆脱synchronized块。 但是,它是一种外部依赖。 但是因为它是Apache Commons Lang并且它被彻底使用,我想这是可以接受的。 它实际上与SimpleDateFormat用法非常相似:

 FastDateFormat fastDateFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mmX"); try { Date fastDate = fastDateFormat.parse("2016-03-23T18:21+01:00"); System.out.println(fastDate); } catch (ParseException e) { LOG.error("Date time parsing exception", e); } 

JodaTime

使用Joda-Time,您可能会认为以下工作:

 DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser(); LocalDateTime dateTime = LocalDateTime.parse("2016-03-23T20:48+01:00", parser); System.out.println(dateTime); // 2016-03-23T20:48:00.000 

不幸的是,无论你把它放在最后位置(Z,+ 03:00,……),结果都是一样的。 显然,它不起作用。
好吧,你真的应该直接解析它:

 DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser(); DateTime dateTime = parser.parseDateTime("2016-03-23T21:12:23+04:00"); System.out.println(dateTime); // 2016-03-23T18:12:23.000+01:00 

现在好了。 请注意,与其他答案不同,我使用dateTimeParser()不是 dateTime() 。 我注意到他们之间的行为有微妙但重要的区别(Joda-Time 2.9.2)。 但是,我留给读者测试并确认。

正如已经建议的那样使用SimpleDateFormat。

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); String date = sdf.format(new Date()); System.out.println(date); Date d = sdf.parse(date); 

我的猜测是你寻找的格式/模式是yyyy-MM-dd'T'HH:mm:ss另外看看http://www.w3schools.com/schema/schema_dtypes_date.asp

使用Joda Time,您将执行以下操作:

 DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); // ISO8601 (XML) Date/time DateTime dt = fmt.parseDateTime("2000-01-01T12:00:00+100"); // +1hr time zone System.out.println(fmt.print(dt)); // Prints in ISO8601 format 

线程安全,不可变且简单。

只需在java中使用SimpleDateFormat,我们就可以做到这一点……

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); Date date = sdf.parse("2011-12-31T15:05:50+1000"); 

Perfect方法,使用XMLGregorianCalendar:

 GregorianCalendar calendar = new GregorianCalendar(); calendar.setTime(v); DatatypeFactory df = DatatypeFactory.newInstance(); XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar(calendar); return dateTime.toString(); 

您可以使用SimpleDateFormat对任何格式的日期进行解析和格式化

我建议使用类javax.xml.bind.DatatypeConverter中内置的java。 它可以处理大多数xml简单类型的转换。 对于必须通过Calendar对象的日期来说有点麻烦,但另一方面它处理可能出现在xml datetime字段中的所有区域信息变体。

来自xml:

  Calendar c = DatatypeConverter.parseDateTime("2015-10-21T13:25"); Date d = c.getTime(); 

到xml:

  Date yourDate = new Date() Calendar c = Calendar.getInstance(); c.setTime(yourDate); String xmlDateTime = DatatypeConverter.printDateTime(c); 

要符合ISO8601,时区必须采用+ HH:MM或-HH:MM格式

使用Simpledateformat,您必须使用XXX而不是Z(请参阅NovelGuy答案)

 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"); 

在不知道您需要什么格式的情况下,通用响应是:您将需要DateFormat或SimpleDateFormat。 这里有一个很好的教程。