Use the java.time package (Java 8+). The old Date and Calendar
classes are mutable, confusingly designed, and should be avoided.
The core types
Java
import java.time.*;
LocalDate date = LocalDate.now(); // 2026-08-22
LocalTime time = LocalTime.now(); // 14:30:05
LocalDateTime dt = LocalDateTime.now(); // both
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Kathmandu"));
Instant now = Instant.now(); // UTC timestamp| Type | Use for |
|---|---|
LocalDate |
a date with no time — birthdays, due dates |
LocalTime |
a time with no date — opening hours |
LocalDateTime |
both, no timezone |
ZonedDateTime |
both, with timezone — meetings, schedules |
Instant |
a machine timestamp — logs, "created at" |
Creating specific values
Java
LocalDate d = LocalDate.of(2026, 8, 22);
LocalDate parsed = LocalDate.parse("2026-08-22");
LocalDateTime dt = LocalDateTime.of(2026, 8, 22, 14, 30);Arithmetic
All these types are immutable — every operation returns a new object:
Java
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
LocalDate yearEnd = today.withDayOfMonth(31).withMonth(12);
System.out.println(today); // unchangedComparing
Java
today.isBefore(other);
today.isAfter(other);
today.isEqual(other);Differences
Java
import java.time.temporal.ChronoUnit;
long days = ChronoUnit.DAYS.between(start, end);
Period p = Period.between(start, end); // date-based
System.out.println(p.getYears() + "y " + p.getMonths() + "m " + p.getDays() + "d");
Duration dur = Duration.between(startTime, endTime); // time-based
System.out.println(dur.toHours() + " hours");Formatting
Java
import java.time.format.DateTimeFormatter;
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd MMM yyyy");
System.out.println(today.format(fmt)); // 22 Aug 2026
LocalDate back = LocalDate.parse("22/08/2026",
DateTimeFormatter.ofPattern("dd/MM/yyyy"));Pattern letters: yyyy year, MM month, dd day, HH hour (24),
mm minutes, ss seconds, EEEE weekday name.
Store UTC, display local
Persist Instant (or a UTC timestamp) in the database, and convert to the
user's zone only when displaying. Storing local times without a zone is
how you end up with events an hour off after a DST change.
Java
Instant stored = Instant.now();
ZonedDateTime shown = stored.atZone(ZoneId.of("Asia/Kathmandu"));