Java Programs›Date & Time›Convert Time Between Time Zones

Convert Time Between Time Zones in Java

intermediate·  Date & Time  ·  Date & Time

Problem

A ZonedDateTime pairs a date-time with a region's time-zone rules, so the same instant can be shown as the correct local time anywhere, daylight saving included.

A meeting starts at 09:30 on 9 March 2026 in India; show the local time for attendees in London, New York and Tokyo.

Input
2026-03-09 09:30 Asia/Kolkata
Output
London 04:00, New York 00:00, Tokyo 13:00

Java Program

Java
import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; public class ConvertTimeZones { public static void main(String[] args) { ZonedDateTime india = ZonedDateTime.of(LocalDateTime.of(2026, 3, 9, 9, 30), ZoneId.of("Asia/Kolkata")); DateTimeFormatter f = DateTimeFormatter.ofPattern("d MMM yyyy HH:mm (xxx)", Locale.ENGLISH); String[] zones = {"Asia/Kolkata", "Europe/London", "America/New_York", "Asia/Tokyo"}; for (String zone : zones) { ZonedDateTime local = india.withZoneSameInstant(ZoneId.of(zone)); // same moment, different clock System.out.println(String.format("%-17s %s", zone, local.format(f))); } } }

Output

Asia/Kolkata 9 Mar 2026 09:30 (+05:30) Europe/London 9 Mar 2026 04:00 (+00:00) America/New_York 9 Mar 2026 00:00 (-04:00) Asia/Tokyo 9 Mar 2026 13:00 (+09:00)

Core Logic

withZoneSameInstant keeps the moment fixed and recalculates the wall-clock time for another zone.

How It Works
  1. 1ZonedDateTime.of(..., ZoneId.of("Asia/Kolkata")) fixes the meeting in Indian time (UTC+05:30).
  2. 2For each target zone, withZoneSameInstant(ZoneId.of(zone)) converts it.
  3. 3The xxx pattern letter prints each zone's UTC offset.
  4. 4String.format("%-17s ...") pads the zone names into a neat column.
New York shows −04:00, not −05:00, because US daylight saving began on 8 March 2026 — the zone rules handle that automatically.
💡

Key Point: Use region IDs such as America/New_York rather than fixed offsets like -05:00, so daylight-saving changes are applied for you.

Key Concepts

ZonedDateTimeZoneIdwithZoneSameInstant()UTC offset

Approach 2: Starting from a UTC Instant

Java
import java.time.Instant; import java.time.ZoneId; public class ConvertTimeZonesInstant { public static void main(String[] args) { Instant moment = Instant.parse("2026-03-09T04:00:00Z"); // a single point on the UTC timeline System.out.println("UTC instant: " + moment); System.out.println("In Kolkata: " + moment.atZone(ZoneId.of("Asia/Kolkata")).toLocalDateTime()); System.out.println("In New York: " + moment.atZone(ZoneId.of("America/New_York")).toLocalDateTime()); } }

Output

UTC instant: 2026-03-09T04:00:00Z In Kolkata: 2026-03-09T09:30 In New York: 2026-03-09T00:00

Core Logic

Servers usually store times as an Instant — a point on the UTC timeline — and convert to a zone only when displaying it.

How It Works
  1. 1Instant.parse("2026-03-09T04:00:00Z") reads a UTC timestamp (the Z means UTC).
  2. 2atZone(ZoneId.of(...)) attaches a zone, producing a ZonedDateTime.
  3. 3toLocalDateTime() drops the zone to show just the local clock reading.
04:00 UTC is 09:30 in Kolkata and midnight in New York — the same moment as the main program.
💡

Key Point: Store instants in UTC and convert at the edges; storing local times without a zone makes them ambiguous later.

Key Concepts

InstantInstant.parse()atZone()

Interview Questions

What's the difference between withZoneSameInstant and withZoneSameLocal?

withZoneSameInstant keeps the moment and changes the clock reading. withZoneSameLocal keeps the clock reading and changes the moment.

How do you list all available time zones?

ZoneId.getAvailableZoneIds() returns every region ID, such as "Europe/London".

Learn the Concept

Related Programs