简体   繁体   English

在Java 7中格式化ISO 8601

[英]Formatting ISO 8601 in Java 7

I have date format like this 2016-11-25T09:29:10.588+01:00 我有这样的日期格式2016-11-25T09:29:10.588+01:00

I want to convert this to milliseconds and later while printing I have to again convert milliseconds to " yyyy-MM-dd HH:mm:ss.SSS " this format. 我想将其转换为milliseconds ,然后在打印时再将毫秒转换为“ yyyy-MM-dd HH:mm:ss.SSS ”这种格式。

static FastDateFormat alarmDateFormat = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS");
DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSXXX");
df1.setTimeZone(TimeZone.getTimeZone("UTC"));
String string1 = "2016-11-25T09:29:10.588+01:00";
Date result1 = df1.parse(string1);
long timeStamp = result1.getTime();
System.out.println("timeStamp : " +timeStamp);
String eventTime = alarmDateFormat.format(timeStamp);
System.out.println("AfterConverting : " + eventTime);

Result : 结果:

timeStamp : 1480062550588
AfterConverting : 2016-11-25 13:59:10.588

Date is proper but the time is different. Date是适当的,但时间是不同的。 I have tried setting timezone to "UTC" but it did't help. 我尝试将时区设置为“ UTC”,但没有帮助。

Please note: In Java 8 it works fine with other libraries like Instant and all but we wanted in Java 7. 请注意:在Java 8中,它可以与其他库(例如Instant和其他所有库)一起正常工作,但在Java 7中却需要所有库。

You're calling setTimeZone in df1 , but this formatter is used only for parsing, and it won't have any effect in formatting. 您正在df1调用setTimeZone ,但是此格式化程序仅用于解析,并且对格式化没有任何影响。

To format the date to a specific timezone, you must set it in the other formatter (if you don't set, the formatter uses the JVM default timezone). 要将日期格式化为特定的时区,必须在另一个格式化程序中进行设置(如果未设置,则格式化程序将使用JVM默认时区)。 Also, you don't need to rely on another class such as FastDateFormat , you can simply use another SimpleDateFormat . 另外,您无需依赖其他类(例如FastDateFormat ,只需使用另一个SimpleDateFormat

But to get exactly the same date/time, you need to use the same offset used in the input ( +01:00 ). 但是要获得完全相同的日期/时间,您需要使用输入中使用的相同偏移量( +01:00 )。 Date objects don't keep this information , so you must extract it from the input. Date对象不保留此信息 ,因此您必须从输入中提取它。 One way would be to use substring : 一种方法是使用substring

SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSXXX");
String string1 = "2016-11-25T09:29:10.588+01:00";
Date result1 = df1.parse(string1);
long timeStamp = result1.getTime();
System.out.println("timeStamp : " + timeStamp);

// extract the +01:00 offset from the input
String offset = string1.substring(23);
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
// set the offset in the formatter (so output is converted to it)
df2.setTimeZone(TimeZone.getTimeZone("GMT" + offset));
String eventTime = df2.format(timeStamp);
System.out.println("AfterConverting : " + eventTime);

The output will be: 输出将是:

timeStamp : 1480062550588 时间戳:1480062550588
AfterConverting : 2016-11-25 09:29:10.588 转换后:2016-11-25 09:29:10.588

If you want to keep using FastDateFormat , it's also possible to set the timezone in it: 如果您想继续使用FastDateFormat ,也可以在其中设置时区:

FastDateFormat f = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS", TimeZone.getTimeZone("GMT" + offset));
String eventTime = f.format(timeStamp);

Java new Date/Time API Java新的日期/时间API

The old classes ( Date , Calendar and SimpleDateFormat ) have lots of problems and design issues , and they're being replaced by the new APIs. 旧的类( DateCalendarSimpleDateFormat )存在很多问题设计问题 ,并且已被新的API取代。

For Java 7 , you can use the ThreeTen Backport , a great backport for Java 8's new date/time classes. 对于Java 7 ,您可以使用ThreeTen Backport ,这是Java 8的新日期/时间类的绝佳反向端口 And for Android , you'll also need the ThreeTenABP (more on how to use it here ). 对于Android ,您还需要ThreeTenABP (更多有关如何在此处使用它的信息 )。

With this, you can parse the input to a org.threeten.bp.OffsetDateTime and use a org.threeten.bp.format.DateTimeFormatter for the output. 这样,您可以将输入解析为org.threeten.bp.OffsetDateTime并使用org.threeten.bp.format.DateTimeFormatter作为输出。 In this case, the OffsetDateTime keeps the offset information, so you don't need to set it in the formatter: 在这种情况下, OffsetDateTime会保留偏移量信息,因此您无需在格式化程序中进行设置:

OffsetDateTime odt = OffsetDateTime.parse(string1);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println("timeStamp : " + odt.toInstant().toEpochMilli());
System.out.println("AfterConverting : " + odt.format(fmt));

The output is the same: 输出是相同的:

timeStamp : 1480062550588 时间戳:1480062550588
AfterConverting : 2016-11-25 09:29:10.588 转换后:2016-11-25 09:29:10.588

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM