有没有一种简单的方法将Java Date转换为XML日期字符串格式,反之亦然?
干杯,
Andez
答案 0 :(得分:22)
我在这里猜测“XML日期格式”你的意思是“2010-11-04T19:14Z”。它实际上是ISO 8601格式。
您可以使用SimpleDateFormat转换它,正如其他人建议的那样,FastDateFormat或使用Joda Time,我认为这是为this purpose特别创建的。
正如 earnshae 在评论中所述,可以通过示例改进这个答案。
首先,我们必须明确原来的答案已经过时了。这是因为Java 8引入了操作日期和时间的类 - java.time
包应该是有意义的。如果你有幸使用Java 8,你应该使用其中之一。但是,这些事情很难做到。
考虑这个例子:
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字符串,似乎这个类没用。
幸运的是,有一个类允许解析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
。根据具体情况,您必须在LocalDateTime
和ZonedDateTime
之间进行选择
当然,您可以轻松地在这两者之间进行转换,因此它应该不是问题:
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 ...),您可能需要使用其他东西。
我不是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
已同步,因此您至少可以摆脱同步块。但是,它是一种外部依赖。但由于它是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);
}
使用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)。但是,我留给读者测试并确认。
答案 1 :(得分:19)
正如已经建议的那样使用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
答案 2 :(得分:9)
使用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
线程安全,不可变且简单。
答案 3 :(得分:8)
Perfect方法,使用XMLGregorianCalendar:
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(v);
DatatypeFactory df = DatatypeFactory.newInstance();
XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar(calendar);
return dateTime.toString();
答案 4 :(得分:7)
只需在java中使用SimpleDateFormat,我们就可以做到这一点......
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = sdf.parse("2011-12-31T15:05:50+1000");
答案 5 :(得分:4)
我建议使用类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);
修改强>
在Java 9及更高版本中,DatatypeConverter类不再公开可见,因为它属于javax.xml.bind包。有关更多信息和可能的解决方案,请参阅this question。在这种情况下, loic vaugeois 提出的使用XmlGregorianCalendar的解决方案要好得多。
答案 6 :(得分:3)
您可以使用SimpleDateFormat
对任何格式的日期进行解析和格式设置答案 7 :(得分:2)
要符合ISO8601,时区的格式必须为+ HH:MM或 - HH:MM
使用Simpledateformat,您必须使用XXX而不是Z(请参阅NovelGuy答案)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
答案 8 :(得分:1)
在不知道您需要什么格式的情况下,通用响应是:您将需要DateFormat或SimpleDateFormat。 here上有一个很好的教程。