简体   繁体   中英

Date conversion from yyyy-MM-dd HH:mm:ss to ISO date yyyy-MM-dd'T'HH:mm:ssXXX format issue

I'm trying to convert date format from yyyy-MM-dd HH:mm:ss to ISO date format yyyy-MM-dd'T'HH:mm:ss+5:30, and tested it by below code and it was working fine when ran on eclipse and causing an issue on deployment to server through jar.

The issue is date(input: 2016-01-08 10:22:03) is converted to something like, 2016-01-08T10:22:03Z instead of 2016-01-08T10:22:03+5:30.

Note: I'm using Java 8.

Following is the code used to convert the date,

 SimpleDateFormat outputDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
 SimpleDateFormat inputDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 String FinalDate = outputDate.format(inputDate.parse(pickupDate));
 System.out.println(finalDate);

Other weird experience is, on some machine the issue is not reproducible and in some machine the issue exists. Is it something machine or JVM dependent? Please help.

Thank you in advance.

As by documentation of SimpleDateFormat:

For formatting, if the offset value from GMT is 0, "Z" is produced. If the number of pattern letters is 1, any fraction of an hour is ignored. For example, if the pattern is "X" and the time zone is "GMT+05:30", "+05" is produced.

So my guess is probably to check the timezone of your server. Since it thinks that the timezone of the entered date is GMT 0.

java.time

If using Java 8 or later, you should be using the java.time classes rather than those notoriously troublesome date-time classes, java.util.Date/.Calendar.

ISO 8601

Your input strings are close to the standard ISO 8601 format. The java.time classes use these standard formats by default when parsing and generating textual representations of date-time values. No need to define a coded parsing pattern for such standard inputs.

To fully comply with ISO 8601, replace that SPACE in the middle with a T .

String inputStandardized = "2016-01-08 10:22:03".replace( " " , "T" );

Parsing Without Time Zone Or Offset

This string has no offset-from-UTC or time zone, so we first create a LocalDateTime .

LocalDateTime localDateTime = LocalDateTime.parse( inputStandardized );

Such objects are a vague idea of a date-time but are not really on the timeline. To define a real moment on the timeline we must apply a time zone.

ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = localDateTime.atZone( zoneId );

Apply Time Zone

Note that that particular date + time may not be valid in the specified time zone; java.time adjusts as necessary. Be sure to read the documentation to understand the adjustment behavior.

Formatted Strings

The toString method on ZonedDateTime by default generates a String in the format you desire, except extended to append the name of the time zone in square brackets.

String output = zdt.toString();

2016-01-08T10:22:03+05:30[Asia/Kolkata]

This extension to include time zone name makes much sense. A time zone is not just an offset-from-UTC, it also includes the present and historical rules for handling anomalies such as Daylight Saving Time (DST).

If you really do not want that appended time zone name, against my advice, you can use an alternate formatting pattern, ISO_OFFSET_DATE_TIME , already defined in java.time as a constant.

DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME ;
String output = zdt.format( formatter );

2016-01-08T10:22:03+05:30

Pad Hour Of Offset

By the way, you can avoid problems by always including a leading padding zero in the hours of your offset-from-UTC. So use +05:30 rather than +5:30 as seen in the Question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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