tl;dr
Your India time is correctly adjusted 10.5 hours ahead of Chicago time. Feature, not a bug. (I am assuming your :56
seconds was a typo in your Question.)
If you want no such adjustment, but instead want the same date and same time-of-day assigned to a different time zone, then do this:
ZonedDateTime.parse(
"Mon May 9 09:34:13 CDT 2016" , // If at all possible, avoid using such an awful format for exchanging date-time strings. Always use standard ISO 8601 formats instead.
DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" )
) // Returns a `ZonedDateTime` object.
.withZoneSameLocal(
ZoneId.of( "Asia/Kolkata" )
) // Returns a fresh `ZonedDateTime` object, with values based on the original but for the change in assigned zone.
.toString() // Generates a String is standard ISO 8601 format, extending the standard by appending the name of the time zone in square brackets.
2016-05-09T09:34:13+05:30[Asia/Kolkata]
We get the same date and same time-of-day, but a different offset-from-UTC means this is a different moment, a different point on the timeline.
Correct values
[Note: I am assuming the :56
in your Mon May 09 20:04:56 IST 2016
was a typo, and should have been :13
. ]
The strings Mon May 9 09:34:13 CDT 2016
and Mon May 09 20:04:13 IST 2016
represent the same moment. This is a feature, not a bug. If by CDT
you mean a time zone such as America/Chicago
, that value on that date represents a moment five hours behind UTC, -05:00
. If by IST
, you mean a time zone such as Asia/Kolkata
, India on that date is five and a half hours ahead of UTC, +05:30
. Add those offsets together, and we get a difference of ten and a half hours. This fits: 09:34:13
plus 10.5 hours is 20:04:13
.
In other words, if someone in Chicago is talking to someone in Kolkata on the telephone, if they both look up at the time on the clock on their own wall, one will see 09:34:13 while the other sees 20:04:13.
Perhaps you wanted to purposely not adjust for time zone, but re-create the same date with the same time-of-day but in a different time zone. This would not be the same moment, this would a different point on the timeline. See below for such code.
java.time
You are using troublesome old classes that were supplanted long ago by the modern java.time classes.
When possible, avoid manipulating strings as a way of handling date-time. Instead, use smart objects, not dumb strings.
Instant instant = Instant.now() ; // Capture current moment in UTC.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, but different wall-clock time.
If you must exchange date-time values as text, use standard ISO 8601 formats rather than formats such as seen in your Question.
Also, never use the 3-4 letter pseudo-time-zones such as CDT
or IST
. These are not true time zones, are not standardized, and many are not unique(!). Use full time zone names is the IANA-specified Continent/Region
format.
But to your Question directly, parsing the string Mon May 9 09:34:13 CDT 2016
. Define a formatting pattern to match.
String input = "Mon May 9 09:34:13 CDT 2016";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
zdt.toString(): 2016-05-09T09:34:13-05:00[America/Chicago]
ZonedDateTime::withZoneSameInstant
Adjust into India time.
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata );
zdtKolkata.toString(): 2016-05-09T20:04:13+05:30[Asia/Kolkata]
Same behavior as you saw with the legacy classes. Adding 10.5 hours to 09:34:13 gets us 20:04:13. Same moment, same point on the timeline, but different wall-clock time.
ZonedDateTime::withZoneSameLocal
But what if you want the same date and same time-of-day, but switch out the time zone? This would result in a different moment, different points on the timeline (assuming the two zones don’t share the same offset). The ZonedDateTime
does support this manipulation via the ZonedDateTime::withZoneSameLocal(ZoneId zone)
method.
ZonedDateTime zdtSameLocalKolkata = zdt.withZoneSameLocal( zKolkata );
zdtSameLocalKolkata.toString(): 2016-05-09T09:34:13+05:30[Asia/Kolkata]
Now we see the time-of-day unchanged, still 09:34:13. But the offset-from-UTC is different than Chicago, so we know this does not represent the same moment.
You can verify the fact they are different moments by adjusting both into UTC. The easy way to make that adjustment is to extract Instant
object. An Instant
is always in UTC by definition.
Instant instantOfZdtChicago = zdt.toInstant() ;
Instant instantOfZdtSameLocalKolkata = zdtSameLocalKolkata.toInstant():
instantOfZdtChicago.toString(): 2016-05-09T14:34:13Z
instantOfZdtSameLocalKolkata.toString(): 2016-05-09T04:04:13Z
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?