Formatting ISO 8601 in Java 7

怎甘沉沦 提交于 2019-12-11 07:28:23

问题


I have date format like this 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.

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. I have tried setting timezone to "UTC" but it did't help.

Please note: In Java 8 it works fine with other libraries like Instant and all but we wanted in Java 7.


回答1:


You're calling setTimeZone in df1, but this formatter is used only for parsing, and it won't have any effect in formatting.

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). Also, you don't need to rely on another class such as FastDateFormat, you can simply use another SimpleDateFormat.

But to get exactly the same date/time, you need to use the same offset used in the input (+01:00). Date objects don't keep this information, so you must extract it from the input. One way would be to use 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
AfterConverting : 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 f = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss.SSS", TimeZone.getTimeZone("GMT" + offset));
String eventTime = f.format(timeStamp);

Java new Date/Time API

The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

For Java 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).

With this, you can parse the input to a org.threeten.bp.OffsetDateTime and use a org.threeten.bp.format.DateTimeFormatter for the output. In this case, the OffsetDateTime keeps the offset information, so you don't need to set it in the formatter:

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
AfterConverting : 2016-11-25 09:29:10.588



来源:https://stackoverflow.com/questions/46300515/formatting-iso-8601-in-java-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!