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

And*_*dez 21 java xml string date

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

干杯,

Andez

Paw*_*yda 23

原始答案

我猜这里的"XML Date Format"你的意思是"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
Run Code Online (Sandbox Code Playgroud)

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

System.out.println(dateTime.getChronology()); // ISO
Run Code Online (Sandbox Code Playgroud)

这实际上是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
Run Code Online (Sandbox Code Playgroud)

这里唯一的问题是,你实际上需要使用时区指定.试图解析原始日期时间(即"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]
Run Code Online (Sandbox Code Playgroud)

我建议现在使用这些课程.但是,如果您的工作描述包括考古学(意味着您没有幸运地使用超过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);
}
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

不幸的是,无论你在最后一个位置放置什么(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
Run Code Online (Sandbox Code Playgroud)

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


Ken*_*net 20

正如已经建议的那样使用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);
Run Code Online (Sandbox Code Playgroud)

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


Gar*_*owe 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
Run Code Online (Sandbox Code Playgroud)

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


小智 8

Perfect方法,使用XMLGregorianCalendar:

GregorianCalendar calendar = new GregorianCalendar();
calendar.setTime(v);
DatatypeFactory df = DatatypeFactory.newInstance();
XMLGregorianCalendar dateTime = df.newXMLGregorianCalendar(calendar);
return dateTime.toString();
Run Code Online (Sandbox Code Playgroud)


Sri*_*lam 7

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

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