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

Convert date and time to EST in Java with America/New_York, which switches between EST and EDT. Compare EST5EDT and EST and print the right zone label.

Timeline of 2026 for America/New_York with EST until March 8, EDT until November 1 and EST again, compared with a fixed UTC-5 offset that stays at UTC-5 all year

Converting a date and time to EST in Java means turning it into 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.

Eastern Time conversion comes up 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 of day in January and in July to Eastern Time and compares the result with a fixed offset and the ID EST.

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
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. We first compare the Eastern zone IDs Java knows, including EST5EDT, and see how JDK 25 treats EST. After that, we convert from four starting types, print the right zone label, and 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, the offset from UTC differs in 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 America/New_York with EST until March 8, EDT until November 1 and EST again, compared with a fixed UTC-5 offset that stays at UTC-5 all year
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 in ZoneId and rejects the three-letter abbreviations.

Zone IDZoneId.of(id) on JDK 25Jan 15, 2026Jul 15, 2026Use it?
America/New_YorkRegion zone-05:00-04:00Yes, the preferred ID
EST5EDTRegion zone-05:00-04:00Same as New York after 1966, kept for old systems
US/EasternRegion zone (old alias)-05:00-04:00Works, but TZDB lists it as a backward-compatibility name
ESTZoneRulesExceptionNoneNoneNo
EDT, ETZoneRulesExceptionNoneNoneNo, these are abbreviations, not zone IDs

If our application does not use dates before 1966, we use the zone America/New_York, because it is the preferred ID and gives the right offset for every date.

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 a yearly switch between the two. For all dates after the Uniform Time Act of 1966, it gives the same offsets as America/New_York. 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 changed it back to plain POSIX rules, which differ from New York only before October 30, 1966.

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

The class ZoneId accepts region IDs from the TZDB and offset IDs, and EST is neither. The old three-letter IDs are only reachable through the alias map ZoneId.SHORT_IDS, and this mapping can change in update releases when the TZDB changes.

ZoneId edt = ZoneId.of("EDT");                              // ZoneRulesException: Unknown time-zone ID: EDT
ZoneId estAlias = ZoneId.of("EST", ZoneId.SHORT_IDS);       // America/Panama
boolean panamaDst = estAlias.getRules().isDaylightSavings(Instant.parse("2026-07-15T15:00:00Z"));   // false

On JDK 25, the alias points to America/Panama, which stays at UTC-5 all year because Panama has no daylight saving time. So the alias gives the same wrong July hour as the fixed offset in the intro.

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 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 legacyEst = TimeZone.getTimeZone("EST");
boolean estHasDst = legacyEst.useDaylightTime();                     // false
String unknownId = TimeZone.getTimeZone("EDT").getID();              // "GMT"
boolean newYorkHasDst = TimeZone.getTimeZone("America/New_York").useDaylightTime();   // true
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 call depends on the type that holds the value.

We haveCallResult type
ZonedDateTime in another zonewithZoneSameInstant(eastern)ZonedDateTime
Instant or epoch millisecondsatZone(eastern)ZonedDateTime
LocalDateTime recorded in UTCatZone(ZoneOffset.UTC).withZoneSameInstant(eastern)ZonedDateTime
java.util.Date from an old APItoInstant().atZone(eastern)ZonedDateTime

2.1. From 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]
ZonedDateTime nowInEastern = ZonedDateTime.now(eastern);         // current time in New York

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

2.2. From Instant and UTC Timestamps

An Instant is a moment in UTC without a zone, which makes it the common 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]
ZonedDateTime fromMillis = Instant.ofEpochMilli(1784127600000L).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

More variants of atZone() are in converting Instant to ZonedDateTime.

2.3. From 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. Calling atZone(eastern) on a UTC value only labels it as Eastern Time and keeps the wrong hour.

LocalDateTime utcValue = LocalDateTime.of(2026, 7, 15, 15, 0);        // read from a UTC column
ZonedDateTime easternTime = utcValue.atZone(ZoneOffset.UTC).withZoneSameInstant(ZoneId.of("America/New_York"));   // 2026-07-15T11:00-04:00[America/New_York]
LocalDateTime easternLocal = easternTime.toLocalDateTime();           // 2026-07-15T11:00
ZonedDateTime wrong = utcValue.atZone(ZoneId.of("America/New_York"));  // 2026-07-15T15:00-04:00[America/New_York]

The last value is 4 hours off, because it claims that 15:00 happened in New York. Other ways between the two types are in LocalDateTime to ZonedDateTime.

2.4. From java.util.Date and Calendar

A java.util.Date holds only a moment in milliseconds and has no zone. 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.

Date legacyDate = Date.from(Instant.parse("2026-07-15T15:00:00Z"));
ZonedDateTime converted = legacyDate.toInstant().atZone(ZoneId.of("America/New_York"));   // 2026-07-15T11:00-04:00[America/New_York]
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
calendar.setTime(legacyDate);
int hour = calendar.get(Calendar.HOUR_OF_DAY);                                              // 11

If old code must keep formatting a Date with SimpleDateFormat, we call setTimeZone(TimeZone.getTimeZone(“America/New_York”)) on the formatter, because the formatter, not the Date, decides the zone of the text.

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 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 does not throw, 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 backup tool lets a user in New York pick 2:30 AM on March 8 for a nightly job. 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, which is handy for a banner such as “clocks change on November 1”.

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

Developers who print US East Coast times ask most often about zone labels, locales and the JVM default zone.

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 does not matter to the reader.

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

The default locale of the JVM 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() 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 time zone.

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 and v for ET, and pass Locale.US, so the label does not depend on the server’s locale. The other zone and formatting topics are collected in our Java date-time guides.

7. References

Happy Learning !!

Source Code on Github

Leave a Comment

  1. System.out.println(etDf.format(currentDate.getTime()));

    you are printing a string.
    it will look correct when it is string but when you try to parse this string into java Date object, it will ignore the timezone and create a Date from systems timezone

  2. HI, what do you mean by this So if we are not using dates before 1966 in our application? I recently run into an issue with a date 1949. And I’m getting  uncategorized SQLException for SQL [{call odc_list_accountOpeningRequest_full(?, ?, ?, ?)}]; SQL sta              te [S1009]; error code [0]; HOUR_OF_DAY: 0 -> 1; nested exception is java.sql.SQLException: HOUR_OF_DAY: 0 -> 1,
    If the date is before 1966 what would be the recommended fix?

    Thanks

    • Can you please create and share a simple Java program to reproduce the error? Just to mention, I do not have firsthand experience of handling dates before 1970 or 1966.

  3. A quick question, if we do not use ‘ET’ but use “America/New_York”, will the value be same? In otherwords, the value will automatically use EST and EDT value according to the date-time.

    (“MM/dd/yyyy ‘at’ hh:mma ‘ET'”)

    def ETTestingValue = new Date().format(“yyyy-MM-dd’T’HH:mm:ss.SSS’Z'”, TimeZone.getTimeZone(“America/New_York”));

  4. Wed, May 22, 2019 at 19:24:12:564 EDT: printing an integer: 15
    Wed, May 22, 2019 at 19:24:12:564 EDT: printing a boolean: true
    Wed, May 22, 2019 at 19:24:12:564 EDT: printing a character: c

    how to get this output in java

  5. Great, but what if you don’t know where you are? I try using TimeZone.getDefault(), but that shows the wrong time when xDT. If I use as you say, it works, but it relies on knowing where you are. The machine is set to a locale, it seems like we should be able to access that.

    Thanks, I have been looking for a solution to this for a while (pre-java-8) and this is close.

  6. Daylight Savings Time (DST) refers to savings that can be made during Summer due to more daylight.

    You mixed between EST (Eastern Standard Time) and EDT (Eastern Daylight Time) :
    * EST (UTC-05:00) is used during Winter
    * EDT (UTC-04:00) is used during Summer.

Comments are closed.

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.