Java Date & Time

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);   // unchanged

Comparing

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"));