有没有一种好的简单方法可以将Java Date转换为XML日期字符串格式,反之亦然?
谢谢,
Andez
我猜您所说的“XML日期格式”是指类似于“2010-11-04T19:14Z”的格式。实际上,这是ISO 8601格式。
您可以使用SimpleDateFormat(如其他人所建议的那样)、FastDateFormat或使用Joda Time进行转换,我认为它是专门为此目的而创建的。
正如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
java.time.format.DateTimeParseException
。因此,如果我们想要解析ISO8601字符串,似乎这个类没有用处。
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
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]
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
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
线程安全、不可变且简单。
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(v);
DatatypeFactory df = DatatypeFactory.newInstance();
XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar(calendar);
return dateTime.toString();
只需在Java中使用SimpleDateFormat即可实现此目的...
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = sdf.parse("2011-12-31T15:05:50+1000");
Calendar
对象进行一些繁琐的操作,但另一方面,它可以处理在xml datetime
字段中出现的所有区域信息变体。 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包。有关更多信息和可能的解决方案,请参见此问题。在这种情况下,loic vaugeois提出的使用XmlGregorianCalendar的解决方案要好得多。
为了符合ISO8601标准,时区必须采用+HH:MM或- HH:MM的格式。
使用Simpledateformat时,必须使用XXX代替Z(请参见NovelGuy的回答)。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");