Convert Date and Time to EST/EDT in Java (EST5EDT vs EST)

To convert a date and time to EST in Java, convert it to a ZonedDateTime in America/New_York, which switches between EST (UTC-5) and EDT (UTC-4). Learn why the EST zone ID gives the wrong hour, how EST5EDT differs and how to print EST, EDT or ET.

Java date time

To convert a date and time to EST in Java, we convert it to a ZonedDateTime in the zone America/New_York, which applies EST (UTC-5) in winter and EDT (UTC-4) in summer. The ID “EST” stands for a fixed UTC-5 offset without daylight saving time, so it shows the wrong hour from March to November.

We need the Eastern Time conversion whenever a server keeps timestamps in UTC but shows them to users on the US East Coast, such as a webinar start time or a payment cut-off time.

The following example converts the same UTC time in January and in July, converts an India time to Eastern Time, and shows what a fixed offset and the “EST” ID return.

ZoneId eastern = ZoneId.of("America/New_York");
DateTimeFormatter format = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a z", Locale.US);

ZonedDateTime winter = Instant.parse("2026-01-15T15:00:00Z").atZone(eastern);   // 2026-01-15T10:00-05:00[America/New_York]
ZonedDateTime summer = Instant.parse("2026-07-15T15:00:00Z").atZone(eastern);   // 2026-07-15T11:00-04:00[America/New_York]
String winterText = winter.format(format);                                       // 01/15/2026 10:00 AM EST
String summerText = summer.format(format);                                       // 07/15/2026 11:00 AM EDT

ZonedDateTime india = ZonedDateTime.of(2026, 7, 15, 20, 30, 0, 0, ZoneId.of("Asia/Kolkata"));
ZonedDateTime indiaInEastern = india.withZoneSameInstant(eastern);               // 2026-07-15T11:00-04:00[America/New_York]

ZonedDateTime fixedOffset = Instant.parse("2026-07-15T15:00:00Z")
    .atZone(ZoneOffset.ofHours(-5));                                             // 2026-07-15T10:00-05:00 (one hour behind New York)
ZoneId est = ZoneId.of("EST");                                                   // ZoneRulesException: Unknown time-zone ID: EST

Notice that America/New_York picks the offset from the date, whereas the fixed offset gives 10:00 in July while clocks in New York show 11:00.

Next, we compare the Eastern zone IDs that Java knows, including EST5EDT, and see how JDK 25 treats “EST”. After that, we convert from ZonedDateTime, Instant, LocalDateTime and the legacy Date, and print the right zone label for each date. The last sections handle the two days a year when the clocks change.

1. Difference between EST, EST5EDT and ‘America/New_York’

In the eastern part of the USA, timezone offsets are different during summer and winter. In winter, clocks run on Eastern Standard Time (EST), which is UTC-5. In summer, clocks run on Eastern Daylight Time (EDT), which is UTC-4. The name for both together is Eastern Time (ET).

The switch follows the US daylight saving time rules. EDT starts at 2:00 AM local time on the second Sunday of March and ends at 2:00 AM on the first Sunday of November, so in 2026 New York uses EDT from March 8 to November 1.

Timeline of 2026 for Eastern Time. America/New_York, and also EST5EDT, uses EST (UTC-5) from January 1 to March 8 at 2:00 AM, EDT (UTC-4) until November 1 at 2:00 AM, and EST again until December 31. A fixed UTC-5 offset stays at UTC-5 all year. For the instant 2026-07-15T15:00:00Z, America/New_York gives 11:00 AM EDT, whereas the fixed offset gives 10:00 AM, which is one hour behind New York.
From March 8 to November 1, 2026, a fixed UTC-5 offset is one hour behind New York, whereas America/New_York follows EST and EDT.

A Java zone ID either names a region with its full history of offset changes, such as America/New_York, or names a fixed offset, such as -05:00. JDK 25 accepts the Eastern region IDs and rejects the three-letter abbreviations.

Zone IDZoneId.of(id) on JDK 25Offset on Jan 15, 2026Offset on Jul 15, 2026Use it?
America/New_Yorkregion zone-05:00-04:00Yes, the preferred ID
EST5EDTregion zone-05:00-04:00Works for dates after 1966, kept for old systems
US/Easternregion zone (old alias)-05:00-04:00Works, but the IANA database lists it as an old alias
ESTZoneRulesExceptionnonenoneNo
EDT, ETZoneRulesExceptionnonenoneNo, these are abbreviations, not zone IDs

So if we are not using dates before 1966 in our application, then we should use America/New_York timezone. It is preferred way.

The ID EST5EDT comes from the POSIX time zone format. It means a standard time 5 hours behind UTC called “EST”, a daylight saving time called “EDT”, and an annual switch between the two. The time zone America/New_York is the same as EST5EDT for all dates after the Uniform Time Act of 1966. For older dates, the result depends on the version of the IANA time zone database (TZDB) inside the JDK. TZDB 2024b made EST5EDT an alias of America/New_York, and TZDB 2026d switched it back to the US federal rules, which differ from New York before October 30, 1966.

Always, prefer to use ‘America/New_York’ for Eastern time. And use ‘ET’ in formatted timestamp. It represents EST and EDT both.

1.1. Why ZoneId.of(“EST”) Fails

The class ZoneId accepts region IDs from the TZDB and offset IDs, and the JDK does not accept EST as a region ID. That is why ZoneId.of(“EST”) throws a ZoneRulesException. The old three-letter IDs are only reachable through the alias map ZoneId.SHORT_IDS, and the target of the EST alias differs between JDK releases.

ZoneId est = ZoneId.of("EST");                                // ZoneRulesException: Unknown time-zone ID: EST
ZoneId edt = ZoneId.of("EDT");                                // ZoneRulesException: Unknown time-zone ID: EDT
ZoneId estAlias = ZoneId.of("EST", ZoneId.SHORT_IDS);         // America/Panama on JDK 25, -05:00 on JDK 21.0.12

Both results of the alias have a fixed UTC-5 offset today, because Panama does not use daylight saving time. So the alias gives the same wrong July time as the fixed offset in the intro, and it also changes its ID between JDK releases.

1.2. Why TimeZone.getTimeZone(“EST”) Is Worse

The legacy class java.util.TimeZone still accepts “EST” and returns a fixed UTC-5 zone. On JDK 25, the call also prints a deprecation warning to the console. For an ID that it does not know, such as “EDT” or “ET”, the method getTimeZone() returns the GMT zone without any error, so the formatted time is 4 hours off in summer.

TimeZone est = TimeZone.getTimeZone("EST");              // fixed UTC-5, useDaylightTime() = false
TimeZone edt = TimeZone.getTimeZone("EDT");              // GMT (unknown ID, no exception)
TimeZone eastern = TimeZone.getTimeZone("America/New_York");   // UTC-5 in winter, UTC-4 in summer
WARNING: Use of the three-letter time zone ID "EST" is deprecated and it will be removed in a future release

2. Convert Date Time to EST and EDT (ET Timezone)

A webinar app stores every start time as an Instant in UTC. When an attendee in Boston opens the schedule, the app converts the start time to America/New_York and prints it with the EST or EDT label of that date. The conversion steps depend on the type that holds the date.

2.1. ZonedDateTime

The method withZoneSameInstant() converts a ZonedDateTime to another zone. It keeps the moment on the timeline and changes the local time and the offset. The similar method withZoneSameLocal() keeps the local time and changes only the zone, so it gives a different moment.

ZoneId eastern = ZoneId.of("America/New_York");
ZonedDateTime india = ZonedDateTime.of(2026, 7, 15, 20, 30, 0, 0, ZoneId.of("Asia/Kolkata"));

ZonedDateTime sameMoment = india.withZoneSameInstant(eastern);   // 2026-07-15T11:00-04:00[America/New_York]
ZonedDateTime sameClock = india.withZoneSameLocal(eastern);      // 2026-07-15T20:30-04:00[America/New_York] (another moment)
ZonedDateTime nowInEastern = ZonedDateTime.now(eastern);         // current time in New York

The method ZonedDateTime.now(eastern) reads the current time in Eastern Time, whatever the default time zone of the server is. The method withZoneSameInstant() works the same way for converting date and time between any two timezones.

2.2. Instant and UTC Timestamps

An Instant is a moment in UTC without a zone, which makes it the usual type for stored timestamps. The method atZone() attaches a zone, so the conversion is one call. To go back from an Eastern local time to UTC, we attach the zone first and call toInstant().

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

ZonedDateTime start = Instant.parse("2026-07-15T15:00:00Z").atZone(eastern);    // 2026-07-15T11:00-04:00[America/New_York]
Instant stored = LocalDateTime.of(2026, 7, 15, 11, 0).atZone(eastern).toInstant();   // 2026-07-15T15:00:00Z

For more variants of atZone(), read converting Instant to ZonedDateTime.

2.3. LocalDateTime Without a Zone

A LocalDateTime has no zone, so Java cannot know which moment it describes. Before the conversion, we state the zone in which the value was recorded, for example UTC for a timestamp column, and convert from there. Calling atZone(eastern) on a UTC value would only label it as Eastern Time and keep the wrong hour.

LocalDateTime utcValue = LocalDateTime.of(2026, 7, 15, 15, 0);   // read from a UTC column

ZonedDateTime eastern = utcValue.atZone(ZoneOffset.UTC)
    .withZoneSameInstant(ZoneId.of("America/New_York"));         // 2026-07-15T11:00-04:00[America/New_York]
LocalDateTime easternLocal = eastern.toLocalDateTime();          // 2026-07-15T11:00
ZonedDateTime wrong = utcValue.atZone(ZoneId.of("America/New_York"));   // 2026-07-15T15:00-04:00[America/New_York] (4 hours off)

For other ways between the two types, read LocalDateTime to ZonedDateTime.

2.4. java.util.Date and Calendar

A java.util.Date holds only a moment in milliseconds and has no zone. The zone matters only when we format the Date or read fields from a Calendar, so we set America/New_York on the SimpleDateFormat or on the Calendar.

SimpleDateFormat etFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a z", Locale.US);
etFormat.setTimeZone(TimeZone.getTimeZone("America/New_York"));

Date date = Date.from(Instant.parse("2026-07-15T15:00:00Z"));
String text = etFormat.format(date);                                     // 07/15/2026 11:00 AM EDT

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
calendar.setTime(date);
int hour = calendar.get(Calendar.HOUR_OF_DAY);                           // 11

ZonedDateTime converted = date.toInstant().atZone(ZoneId.of("America/New_York"));   // 2026-07-15T11:00-04:00[America/New_York]

The last line converts the Date to a java.time type. When a library still returns a Date, we convert it with toInstant() and do the rest of the work with ZonedDateTime, which is immutable and thread-safe, whereas SimpleDateFormat is not thread-safe.

3. Printing EST, EDT or ET in the Formatted Time

The pattern letters of DateTimeFormatter decide which zone label appears in the text. The letter z prints the label of that date, so the same pattern gives EST in January and EDT in July. The letter v prints the generic name ET, which is correct all year and replaces the literal text ‘ET’ in a pattern.

PatternJanuary 15, 2026July 15, 2026
zESTEDT
zzzzEastern Standard TimeEastern Daylight Time
vETET
vvvvEastern TimeEastern Time
OGMT-5GMT-4
XXX-05:00-04:00
VVAmerica/New_YorkAmerica/New_York
ZonedDateTime summer = Instant.parse("2026-07-15T15:00:00Z").atZone(ZoneId.of("America/New_York"));

String withLabel = summer.format(DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mma z", Locale.US));   // 07/15/2026 at 11:00AM EDT
String withEt = summer.format(DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mma v", Locale.US));     // 07/15/2026 at 11:00AM ET
String inIndia = summer.format(DateTimeFormatter.ofPattern("hh:mm a z", Locale.forLanguageTag("en-IN")));   // 11:00 am GMT-04:00

We always pass a Locale to the formatter, because the zone label comes from the locale data. With Locale.US, the letter z prints EDT. With the en-IN or en-GB locale, the same pattern prints GMT-04:00 and a lowercase am, so a server with a different default locale prints a different text. More pattern examples are in formatting ZonedDateTime.

4. Handling the Daylight Saving Time Switch

Twice a year, the local clock in New York jumps, and some local times are either missing or happen twice. The class ZonedDateTime resolves both cases with fixed rules, so the code never throws, but the result may not be the time the user typed.

  • On March 8, 2026, clocks jump from 2:00 AM to 3:00 AM. A local time in the gap, such as 2:30 AM, moves forward by one hour to 3:30 AM EDT.
  • On November 1, 2026, clocks go back from 2:00 AM to 1:00 AM, so 1:30 AM happens twice. Java picks the earlier offset (EDT), and withLaterOffsetAtOverlap() gives the second 1:30 AM (EST).
ZoneId eastern = ZoneId.of("America/New_York");

ZonedDateTime inGap = LocalDateTime.of(2026, 3, 8, 2, 30).atZone(eastern);           // 2026-03-08T03:30-04:00[America/New_York]
ZonedDateTime firstPass = LocalDateTime.of(2026, 11, 1, 1, 30).atZone(eastern);      // 2026-11-01T01:30-04:00[America/New_York]
ZonedDateTime secondPass = firstPass.withLaterOffsetAtOverlap();                     // 2026-11-01T01:30-05:00[America/New_York]

For example, a reminder app lets a user in New York pick 2:30 AM on March 8 for a daily backup. That time does not exist on that day, so the job runs at 3:30 AM. When a scheduler must run a job once per day, we keep the schedule in local time and the run history as Instant values in UTC.

To check whether a moment falls in EDT, we ask the zone rules. The method nextTransition() returns the next clock change.

ZoneRules rules = ZoneId.of("America/New_York").getRules();

boolean summerDst = rules.isDaylightSavings(Instant.parse("2026-07-15T15:00:00Z"));   // true
boolean winterDst = rules.isDaylightSavings(Instant.parse("2026-01-15T15:00:00Z"));   // false
ZoneOffset offset = rules.getOffset(Instant.parse("2026-07-15T15:00:00Z"));           // -04:00
ZoneOffsetTransition next = rules.nextTransition(Instant.parse("2026-04-01T00:00:00Z"));   // Transition[Overlap at 2026-11-01T02:00-04:00 to -05:00]

5. EST Conversion FAQs

5.1. Is EST the Same as ET?

No. EST is the winter part of Eastern Time with a fixed UTC-5 offset. ET means Eastern Time, which is EST in winter and EDT in summer. A time written as “10:00 AM EST” in July is one hour off, so we print ET with the pattern letter v when the season is not important to the reader.

5.2. Why Does My Output Show GMT-05:00 Instead of EST?

The locale data of the default JVM locale has no short name for the Eastern zone. The pattern letter z uses the locale data, and locales such as en-IN or en-GB print GMT-05:00 in winter. We pass Locale.US to DateTimeFormatter.ofPattern(), as we saw in section 3.

5.3. Should I Set the JVM Default Time Zone to America/New_York?

No, not for the conversion itself. The default time zone affects every ZonedDateTime.now(), LocalDateTime.now(), new Date().toString() and log timestamp in the app, including the ones in libraries. We pass ZoneId.of(“America/New_York”) to the code that needs Eastern Time, and keep the server on UTC. When a whole app must run in one zone, read how to set the JVM timezone.

5.4. How Do I List All Zone IDs That Java Supports?

We call ZoneId.getAvailableZoneIds(), which returns a Set of every region ID in the TZDB of the running JDK. The set contains America/New_York and EST5EDT, but not EST. The full list with offsets is in supported zone IDs and offsets.

boolean hasNewYork = ZoneId.getAvailableZoneIds().contains("America/New_York");   // true
boolean hasEst = ZoneId.getAvailableZoneIds().contains("EST");                     // false

6. Conclusion

To convert a date and time to EST in Java, we use the zone ID America/New_York with ZonedDateTime. The zone switches between EST (UTC-5) and EDT (UTC-4) on the US daylight saving dates, so the converted hour is right all year.

The ID EST5EDT gives the same result for every date after 1966. The IDs EST and EDT give wrong results or errors, because ZoneId.of() rejects them and TimeZone.getTimeZone() returns either a fixed UTC-5 zone or GMT.

For the text output, we pick the label with the pattern letter (z for EST or EDT, v for ET) and pass Locale.US, so the label does not depend on the server’s locale.

7. References

Happy Learning !!

Source Code on Github

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.