Careeroza
Time Zones and Instant
ZonedDateTime and Instant
Servers should store time as an Instant (UTC) and convert to the user's zone only for display. India uses Asia/Kolkata (UTC+05:30) with no daylight saving; zones like America/New_York change offset during the year.
Example
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZoneId india = ZoneId.of("Asia/Kolkata");
ZonedDateTime launch = ZonedDateTime.of(LocalDateTime.of(2024, 11, 20, 18, 30), india);
System.out.println("India : " + launch);
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd MMM HH:mm z");
for (String zone : new String[] { "UTC", "Europe/London", "America/New_York", "Asia/Tokyo" }) {
ZonedDateTime other = launch.withZoneSameInstant(ZoneId.of(zone));
System.out.printf("%-17s %s%n", zone, other.format(f));
}
Instant instant = launch.toInstant();
System.out.println("Instant : " + instant);
System.out.println("Epoch sec: " + instant.getEpochSecond());
Instant fromDb = Instant.parse("2024-11-20T13:00:00Z");
System.out.println("Same moment? " + instant.equals(fromDb));
System.out.println("Back in IST: " + fromDb.atZone(india).toLocalDateTime());
}
}Output
India : 2024-11-20T18:30+05:30[Asia/Kolkata] UTC 20 Nov 13:00 UTC Europe/London 20 Nov 13:00 GMT America/New_York 20 Nov 08:00 EST Asia/Tokyo 20 Nov 22:00 JST Instant : 2024-11-20T13:00:00Z Epoch sec: 1732107600 Same moment? true Back in IST: 2024-11-20T18:30
Legacy Classes
Old code and some libraries still use java.util.Date and Calendar. Convert at the edges and use java.time inside your code.
Date legacy = new Date();
Instant instant = legacy.toInstant(); // Date -> Instant
Date back = Date.from(instant); // Instant -> Date
LocalDate date = instant.atZone(ZoneId.of("Asia/Kolkata")).toLocalDate();
java.sql.Date sqlDate = java.sql.Date.valueOf(date); // for old JDBC code