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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4099862/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:37:18  来源:igfitidea点击:

Convert Java Date into XML Date Format (and vice versa)

javaxmlstringdate

提问by Andez

Is there a nice and easy way to convert a Java Date into XML date string format and vice versa?

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

Cheers,

干杯,

Andez

安德斯

采纳答案by Pawe? Dyda

Original answer

原答案

I am guessing here that by "XML Date Format" you mean something like "2010-11-04T19:14Z". It is actually ISO 8601format.

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

You can convert it using SimpleDateFormat, as others suggested, FastDateFormat or using Joda Timewhich was I believe especially created for this purpose.

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

Edit: code samples and more

编辑:代码示例等

As earnshaestated in a comment, this answer could be improved with examples.

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

First, we have to make clear that the original answer is pretty outdated. It's because Java 8 introduced the classes to manipulate date and time - java.timepackage should be of interest. If you are lucky enough to be using Java 8, you should use one of them. However, these things are surprisingly difficult to get right.

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

LocalDate(Time) that isn't

LocalDate(Time) 不是

Consider this example:

考虑这个例子:

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

At first it may seem that what we're using here is a local (to the user date and time). However, if you dare to ask, you'll get different result:

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

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

This actually, the ISO time. I believe it should read 'UTC' but nonetheless this has no notion of local time zone. So we should consider it universal.
Please notice, that there is no "Z" at the end of the string we are parsing. Should you add anything apart of date and time, you'll be greeted with java.time.format.DateTimeParseException. So it seems that this class is of no use if we want to parse ISO8601 string.

这实际上是 ISO 时间。我相信它应该读为“UTC”,但它没有本地时区的概念。所以我们应该认为它是通用的。
请注意,我们正在解析的字符串末尾没有“Z”。如果您添加日期和时间之外的任何内容,您将收到java.time.format.DateTimeParseException. 所以如果我们要解析 ISO8601 字符串,这个类似乎没有用。

ZonedDateTime to the rescue

ZonedDateTime 来救援

Fortunately, there is a class that allows for parsing ISO8601 strings - it's a java.time.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

The only problem here is, you actually need to use time zone designation. Trying to parse raw date time (i.e. "2016-03-23T18:21") will result in already mentioned RuntimeException. Depending on the situation you'd have to choose between LocalDateTimeand ZonedDateTime.
Of course you can easily convert between those two, so it should not be a problem:

这里唯一的问题是,您实际上需要使用时区指定。尝试解析原始日期时间(即“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]

I recommend using this classes nowadays. However, if your job description includes archeology (meaning you are not lucky enough to be working with more than 2 year old Java 8...), you may need to use something else.

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

The joy of SimpleDateFormat

SimpleDateFormat 的乐趣

I am not a very big fan of https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html, but sometimes you just have no other choice. Problem is, it is not thread-safe and it will throw a checked Exception(namely ParseException) in your face if it dislikes something. Therefore the code snippet is rather ugly:

我不是 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

快速日期格式

FastDateFormatis synchronized, therefore you can at least get rid of the synchronized block. However, it is an external dependency. But since it's the Apache Commons Langand it is thoroughly used, I guess it is acceptable. It is actually very similar in usage to SimpleDateFormat:

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);
}

JodaTime

乔达时间

With Joda-Time you may think that following works:

使用 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

Unfortunately, no matter what you put at last position (Z, +03:00, ...) the result will be the same. Clearly, it isn't working.
Well, you really should be parsing it directly:

不幸的是,无论您在最后一个位置 (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

Now it will be OK. Please note, that unlike one of other answers, I used dateTimeParser()and notdateTime(). I noticed subtle, but important difference in behavior between them (Joda-Time 2.9.2). But, I leave it to the reader to test it and confirm.

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

回答by Eugene Kuleshov

You can parse and format dates to and from any format using SimpleDateFormat

您可以使用SimpleDateFormat从任何格式解析和格式化日期

回答by javamonkey79

Without knowing exactly what format you need, the generic response is: you're going to want DateFormat or SimpleDateFormat. There is a nice tutorial on both here.

在不确切知道您需要什么格式的情况下,一般的回答是:您将需要 DateFormat 或 SimpleDateFormat。有两个很好的教程在这里

回答by Kennet

As already suggested use SimpleDateFormat.

正如已经建议使用 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);

My guess is that the format/pattern that your looking for is yyyy-MM-dd'T'HH:mm:ssAlso have a look at http://www.w3schools.com/schema/schema_dtypes_date.asp

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

回答by Gary Rowe

Using Joda Timeyou would do the following:

使用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

Thread safe, immutable and simple.

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

回答by Sridhar Nalam

Just by using SimpleDateFormat in java we can do this...

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

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

回答by Belz

The Perfect method, use XMLGregorianCalendar:

Perfect 方法,使用 XMLGregorianCalendar:

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

回答by arkhos

To comply with ISO8601, the timezone must be in the format +HH:MM or - HH:MM

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

With Simpledateformat you must use XXX instead of Z (see NovelGuy answer)

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

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

回答by stenix

I would recommend to use the java built in class javax.xml.bind.DatatypeConverter. It can handle conversion to and from most of the xml simple types. It is a little bit cumbersome for dates that you have to go through a Calendarobject but on the other hand it handles all variants of zone information that can occur in a xml datetimefield.

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

From xml:

来自 xml:

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

To xml:

到 xml:

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

EDIT

编辑

The DatatypeConverter class is no longer publicly visible in Java 9 and above since it belongs to the javax.xml.bind package. See this questionfor more information and possible solutions. The solution proposed by loic vaugeoisto use XmlGregorianCalendar is much better in this case.

DatatypeConverter 类在 Java 9 及更高版本中不再公开可见,因为它属于 javax.xml.bind 包。有关更多信息和可能的解决方案,请参阅此问题。在这种情况下,loic vaugeois提出的使用 XmlGregorianCalendar的解决方案要好得多。