将 Java 日期转换为 XML 日期格式(反之亦然)

2022-09-02 02:13:19

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

干杯

安德兹


答案 1

原始答案

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

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

编辑:代码示例等

正如尹海在评论中所说,这个答案可以通过例子来改进。

首先,我们必须明确原始答案已经过时了。这是因为Java 8引入了这些类来操作日期和时间 - 包应该很有趣。如果你有幸使用Java 8,你应该使用其中之一。然而,这些事情出乎意料地难以正确。java.time

不是本地日期(时间)

请考虑以下示例:

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”。如果您添加除日期和时间之外的任何内容,则将收到 .因此,如果我们要解析ISO8601字符串,那么这个类似乎没有用处。java.time.format.DateTimeParseException

ZonedDate救援时间

幸运的是,有一个类允许解析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”)将导致已经提到的。根据具体情况,您必须在 和 之间进行选择。
当然,您可以轻松地在这两者之间进行转换,因此这应该不是问题:RuntimeExceptionLocalDateTimeZonedDateTime

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 的忠实粉丝,但有时你别无选择。问题是,它不是线程安全的,如果它不喜欢某些东西,它会把一个检查(即)扔到你的脸上。因此,代码片段相当丑陋:ExceptionParseException

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已同步,因此您至少可以摆脱已同步的块。但是,它是一种外部依赖关系。但是由于它是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

现在一切都会好起来的。请注意,与其他答案之一不同,我使用了而不是.我注意到他们之间微妙但重要的行为差异(Joda-Time 2.9.2)。但是,我把它留给读者来测试和确认。dateTimeParser()dateTime()


答案 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);

我的猜测是,您寻找的格式/模式也要看看 http://www.w3schools.com/schema/schema_dtypes_date.aspyyyy-MM-dd'T'HH:mm:ss