Zoned date time is not giving est time

140 Views Asked by At

I want to convert the date and time to EST zone and I tried using calendar for some reason it is not converting the time even though it is setting the timezone correctly. And I am trying zonedDateTime and it is also working same.

ZoneId estZone = ZoneId.of("America/New_York");
ZonedDateTime estTime =       ZonedDateTime.now(estZone);
 System.out.println(Date.from(estTime.toInstant()));

My output is: Mon Oct 16 16:17:13 IST 2023.

But i set my zone id to America. And estTime.toLocalDateTime is giving corrected time in EST but I am not able to convert it into Date return type as it is throwing Instant class errors

I need some explanation on this

1

There are 1 best solutions below

0
Basil Bourque On

Use real time zone

ZoneId estZone = ZoneId.of("America/New_York");

EST is not a real time zone. Use such pseudo-zones only for presentation to the user, not for logic or data. Pseudo-zones are not standardized, and are not even unique(!).

And the time zones usually associated with “Eastern” time are currently observing Daylight Saving Time (DST). So the pseudo-zone label would be EDT rather than EST.

So, let’s use this:

ZoneId zoneNewYork = ZoneId.of( "America/New_York" ) ;

Use java.time classes

ZonedDateTime zdtNewYork = ZonedDateTime.now( zoneNewYork );

Good. You captured the current moment as seen with the wall-clock time & calendar used by the people of the New York region.

To generate text in standard ISO 8601 format wisely extended to append the name of the time zone in brackets, merely call toString.

String output = zdtNewYork.toString() ;

To generate localized text, use DateTimeFormatter.ofLocalizedDateTime.

Avoid legacy date-time classes

Date.from(estTime.toInstant())

Bad. You needlessly involved the terribly flawed legacy class java.util.Date.

Avoid the legacy date-time classes. Use only java.time classes.

As for the behavior you encountered, the Date#toString method lies to us. While generating its text, the method dynamically applies the JVM’s current default time zone. One of many reasons to avoid this class.

JDBC

You commented on storing this moment in a database.

Your table column should be of a type akin to the SQL standard type TIMESTAMP WITH TIME ZONE.

The JDBC standard maps the Java class OffsetDateTime to that type.

OffsetDateTime odt = zdtNewYork.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;

Retrieval.

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdtNewYork = odt.atZoneSameInstant( zoneNewYork ) ;

Search to learn more. This has been covered many times on Stack Overflow.

Using legacy classes

You commented:

we need to use date for legacy purpose so I need one date object that can represent the current time as in EST

The java.util.Date class represents a moment as seen with an offset of zero hours-minutes-seconds from the temporal meridian of UTC. So asking for a java.util.Date object to represent a moment as seen in a time zone like America/New_York is impossible.

The replacement for java.util.Date is java.time.Instant. Both represent a moment as seen in UTC (an offset of zero). You can convert back and forth via new methods added to the old classes.

Instant instant = Instant.now() ;
java.util.Date d = java.util.Date.from( instant ) ;

And going the other direction:

Instant instant = d.toInstant() ;

When converting, be mindful of possible data loss. The legacy class resolves to milliseconds while the modern class has a much finer resolution of nanoseconds.

The java.util.Calendar class, or rather its subclass java.util.GregorianCalendar, can represent a moment as seen in a particular time zone. If need be, you can convert back and forth to/from its replacement class, java.time.ZonedDateTime.

Avoid these legacy classes wherever possible. They are a bloody mess of poor design and wacky features.

If you have a specific case where you need to interoperate with old code not yet updated to java.time, post a Question on Stack Overflow with those specific details.