I am trying to convert Date with GMT +5:30
to EST
with java 8 ZonedDateTime
.
String inputDate = "2015/04/30 13:00";
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm", Locale.US);
LocalDateTime local = LocalDateTime.parse(inputDate, sourceFormatter);
// local : 2015-04-30T13:00
//Combining this local date-time with a time-zone to create a ZonedDateTime.
ZonedDateTime zoned = local.atZone(TimeZone.getTimeZone("GMT+5:30").toZoneId());
// zoned : 2015-04-30T13:00+05:30[GMT+05:30]
ZonedDateTime zonedUS = zoned.withZoneSameInstant(TimeZone.getTimeZone("GMT-5:00").toZoneId());
// zonedUS : 2015-04-30T02:30-05:00[GMT-05:00]
I am expecting 3:30 AM EST
but what I am getting is 2:30 AM EST
as 1 PM IST= 3:30AM EST
. What am I missing?
It seems that whatever service you found was being over-helpful in interpreting what you meant and assumed North American Eastern Daylight Time (EDT) when you specified EST (Eastern Standard Time). Most, not all of the places using EST as standard time are using daylight saving time and hence were on EDT or offset UTC-04:00 on the date you use, April 30, 2015.
If it makes sense in your situation, you should always prefer to give time zone in the region/city format, as Asia/Kolkata and America/New_York. If you intended Eastern Time as in New York or Montréal, one may say that your “time zone” of GMT-5:00 was wrong and the cause of your unexpected result.
So your code becomes for example:
String inputDate = "2015/04/30 13:00";
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm", Locale.US);
LocalDateTime local = LocalDateTime.parse(inputDate, sourceFormatter);
// local : 2015-04-30T13:00
//Combining this local date-time with a time-zone to create a ZonedDateTime.
ZonedDateTime zoned = local.atZone(ZoneId.of("Asia/Kolkata"));
// zoned : 2015-04-30T13:00+05:30[Asia/Kolkata]
ZonedDateTime zonedUS = zoned.withZoneSameInstant(ZoneId.of("America/Montreal"));
// zonedUS : 2015-04-30T03:30-04:00[America/Montreal]
I have made one other change: When using the modern classes from java.time
, there is no point in also using the outdated TimeZone
class, so I have taken that out. The code is slightly simpler, and more importantly, ZoneId.of(String)
includes validation of your time zone string so you will discover any spelling error in the time zone name (like when I just happened to type a (
instead of the /
in Asia/Kolkata — such happens all the time).
Most of the above has already been said in comments by Jon Skeet and others. I thought it deserved to go into an answer so it’s plain to see that the question has been answered.
Though the question is old, felt like I could add more to the accepted answer.
A ZonedDateTime
is different from an OffsetDateTime
.
I would prefer to use ZonedDateTime
when I'm getting a time for a specific location like "Asia/Kolkata", "Asia/Shanghai", "US/Pacific" (this time zone will change depending on the day of the year because of Daylight savings).
To illustrate with an example,
var pacific = ZonedDateTime.of(2020,11,01,1,59,0,0,ZoneId.of("US/Pacific"))
var afterAnHour = pacific.plusHours(1)
This will give me a time of
2020-November-01 01:59:00.000 AM -07:00[US/Pacific]
And if i add an hour to it, it will give me a time of
2020-November-01 01:59:00.000 AM -08:00[US/Pacific]
You can see that the hour component is same even after adding an hour to the time. This is because the daylight savings time has kicked in and the time zone is shifted from -07:00 to -08:00.
Now if i use an OffsetDateTime
look what happens.
var offsetNow = OffsetDateTime.of(2020,11,01,1,59,0,0,ZoneOffset.of("-07:00"))
var offsetAfterAnHour = offsetNow.plusHours(1)
The offsetNow will be,
2020-November-01 01:59:00.000 -07:00
And adding an hour to it will be,
2020-November-01 02:59:00.000 -07:00
you can see that the hour component has become 2
after adding an hour.
The key point is a ZonedDateTime
uses ZoneRules
to calculate important properties like Daylight savings time so that it can adjust the time zone accordingly.
While the OffsetDateTime
will not change the zone offset for anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With