Since Java 8, the java.time API replaces the old Date and Calendar classes with immutable, clear types: LocalDate for dates, LocalDateTime for date and time, ZonedDateTime and Instant for real moments. Test code uses them to build test data ("a date 30 days from today") and to compare dates shown in the UI or API.
The old java.util.Date was mutable, not thread-safe, had confusing month numbering (0-based!), and no timezone support. Java 8 introduced java.time — immutable, thread-safe, clear API.
import java.time.*;
import java.time.format.*;
import java.time.temporal.*;
// ── LOCAL DATE (date without time/timezone) ──
LocalDate today = LocalDate.now(); // 2024-03-15
LocalDate date = LocalDate.of(2024, 3, 15); // specific date
LocalDate parsed = LocalDate.parse("2024-03-15");
today.getYear() // 2024
today.getMonthValue() // 3 (1-12, not 0-11!)
today.getMonth() // Month.MARCH
today.getDayOfMonth() // 15
today.getDayOfWeek() // DayOfWeek.FRIDAY
today.getDayOfYear() // 75
today.lengthOfMonth() // 31
today.lengthOfYear() // 366 (leap) or 365
today.isLeapYear() // true/false
// Manipulation (returns NEW object — immutable!)
today.plusDays(10) // 2024-03-25
today.plusMonths(1) // 2024-04-15
today.plusYears(1) // 2025-03-15
today.minusDays(5) // 2024-03-10
today.withDayOfMonth(1) // 2024-03-01 (first of month)
today.withMonth(1) // 2024-01-15
// Comparison
LocalDate other = LocalDate.of(2025, 1, 1);
today.isBefore(other) // true
today.isAfter(other) // false
today.isEqual(other) // false
today.compareTo(other) // negative
// ── LOCAL TIME (time without date/timezone) ──
LocalTime now = LocalTime.now(); // 14:30:45.123
LocalTime time = LocalTime.of(14, 30, 45); // 14:30:45
LocalTime midnight = LocalTime.MIDNIGHT; // 00:00
LocalTime noon = LocalTime.NOON; // 12:00
now.getHour() // 14
now.getMinute() // 30
now.getSecond() // 45
now.getNano() // nanoseconds
now.plusHours(2) // 16:30:45.123
now.truncatedTo(ChronoUnit.MINUTES) // 14:30
// ── LOCAL DATE TIME ──
LocalDateTime dt = LocalDateTime.now();
LocalDateTime dt2 = LocalDateTime.of(2024, 3, 15, 14, 30);
LocalDateTime dt3 = LocalDate.now().atTime(LocalTime.now());
LocalDateTime dt4 = LocalDate.now().atStartOfDay();
// ── ZONED DATE TIME (with timezone) ──
ZonedDateTime zdt = ZonedDateTime.now();
ZonedDateTime mumbai = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
ZonedDateTime nyc = ZonedDateTime.now(ZoneId.of("America/New_York"));
ZoneId.getAvailableZoneIds() // set of all zone IDs
// Convert between zones
ZonedDateTime utc = mumbai.withZoneSameInstant(ZoneOffset.UTC);
// ── INSTANT (machine time — epoch milliseconds) ──
Instant now2 = Instant.now();
long epochMs = now2.toEpochMilli();
Instant fromMs = Instant.ofEpochMilli(epochMs);
Instant plus = now2.plusSeconds(3600); // 1 hour later
// ── PERIOD (date-based duration) ──
Period period = Period.of(1, 2, 15); // 1 year, 2 months, 15 days
Period between = Period.between(LocalDate.of(2020,1,1), LocalDate.now());
between.getYears() // years part
between.getMonths() // months part
between.getDays() // days part
between.toTotalMonths() // total months
LocalDate future = LocalDate.now().plus(period);
// ── DURATION (time-based duration) ──
Duration duration = Duration.ofHours(2).plusMinutes(30);
Duration between2 = Duration.between(LocalTime.of(9,0), LocalTime.of(17,0));
between2.toHours() // 8
between2.toMinutes() // 480
between2.toSeconds() // 28800
// ── DATE TIME FORMATTER ──
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
String formatted = LocalDateTime.now().format(fmt); // "15/03/2024 14:30:45"
LocalDateTime parsed2 = LocalDateTime.parse("15/03/2024 14:30:45", fmt);
// Built-in formatters
DateTimeFormatter.ISO_LOCAL_DATE // 2024-03-15
DateTimeFormatter.ISO_LOCAL_DATE_TIME // 2024-03-15T14:30:45
DateTimeFormatter.ISO_ZONED_DATE_TIME // with timezone
DateTimeFormatter.RFC_1123_DATE_TIME // for HTTP headers
// Locale-sensitive formatting
DateTimeFormatter localFmt = DateTimeFormatter
.ofLocalizedDate(FormatStyle.LONG)
.withLocale(Locale.forLanguageTag("hi-IN")); // Hindi
// ── CHRONO UNITS ──
ChronoUnit.DAYS.between(LocalDate.of(2024,1,1), LocalDate.now())
ChronoUnit.HOURS.between(LocalTime.of(9,0), LocalTime.of(17,0)) // 8
// ── CONVERT FROM OLD API ──
Date oldDate = new Date();
Instant instant = oldDate.toInstant();
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
// Convert to old API
Date converted = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
Why was java.util.Date replaced?
java.util.Date is mutable (not thread-safe), months are 0-indexed (January=0), no timezone support, confusing API. java.time (JSR-310) fixes all: immutable, 1-indexed months, explicit timezone handling, clear separation of date/time/datetime/instant concepts.
Dates in Test Code
// Dynamic test data instead of hard-coded dates that expire
LocalDate checkIn = LocalDate.now().plusDays(7);
LocalDate checkOut = checkIn.plusDays(3);
String uiFormat = checkIn.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); // e.g. 12/10/2026
// Assert an API timestamp is recent (no exact match on time)
Instant created = Instant.parse(response.path("createdAt")); // "2026-10-05T07:15:30Z"
assertTrue(Duration.between(created, Instant.now()).abs().toMinutes() < 5);
// Make time-dependent code testable: inject a Clock
Clock fixed = Clock.fixed(Instant.parse("2026-01-31T10:00:00Z"), ZoneOffset.UTC);
LocalDate today = LocalDate.now(fixed); // always 2026-01-31 in this test
Hard-coded dates are a classic source of tests that pass for months and then fail on a particular day; generate them relative to "now", or inject a fixed Clock.
FAQs
What is the difference between LocalDateTime and ZonedDateTime?
LocalDateTime has no time zone, so it isn't a specific moment; ZonedDateTime includes a zone (for example Asia/Kolkata) and represents an exact instant on the timeline.
How do you format a date in Java?
Use DateTimeFormatter.ofPattern("dd-MM-yyyy") with date.format(formatter), and LocalDate.parse(text, formatter) to parse.
What is the difference between Duration and Period?
Duration measures time in seconds and nanoseconds (hours, minutes); Period measures date-based amounts in years, months and days.