Java LocalDateTime Class: Creation, Formatting and Examples - Quiz

Total: 6 questions

1. 

What is LocalDateTime in Java and how do you create one?

java.time.LocalDateTime (Java 8+) is an immutable, thread-safe class that stores a date and a time without a time zone: year, month, day, hours, minutes, seconds and nanoseconds. In effect it is a LocalDate and a LocalTime in one object.

There is no public constructor; you create objects with factory methods:

  • LocalDateTime.of(2024, 3, 15, 14, 30) — from parts (seconds and nanoseconds are optional);
  • LocalDateTime.of(date, time), date.atTime(14, 30), time.atDate(date), date.atStartOfDay() — from an existing LocalDate and LocalTime;
  • LocalDateTime.parse("2024-03-15T14:30:45") — from an ISO-8601 string;
  • LocalDateTime.now() — the current date and time.

toString() puts the letter T between the date and the time and omits zero seconds and nanoseconds: LocalDateTime.of(2014, 9, 19, 14, 5) prints as 2014-09-19T14:05. Invalid values (of(2024, 2, 30, 10, 0), hour 24) throw DateTimeException immediately.

2. 

Why does LocalDateTime.parse("2024-03-15 10:30") throw an exception, and how do you format and parse a LocalDateTime in a custom format?

Without a formatter, parse() only understands ISO-8601, where the letter T separates the date and the time: "2024-03-15T10:30". At index 10 it finds a space and throws DateTimeParseException: ... could not be parsed at index 10. A date-only string ("2024-03-15") is not parsed either.

A custom format needs a DateTimeFormatter:

DateTimeFormatter dmy = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
String s = LocalDateTime.of(2024, 3, 15, 14, 30).format(dmy); // 15.03.2024 14:30
LocalDateTime dt = LocalDateTime.parse("15.03.2024 14:30", dmy);
DateTimeFormatter us = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a", Locale.ENGLISH); // 03/15/2024 02:30 PM

The AM/PM marker a depends on the locale, so pass a Locale explicitly. If the pattern has no time ("dd.MM.yyyy"), parsing into a LocalDateTime fails with Unable to obtain LocalDateTime from TemporalAccessor — parse into a LocalDate and call atStartOfDay(). A pattern with a zone offset (XXX, Z) throws UnsupportedTemporalTypeException: Unsupported field: OffsetSeconds: the object has no zone, so call atZone() first.

3. 

How do you change and compare LocalDateTime values?

The object is immutable: withYear()…withNano() and with(ChronoField, value) replace one field, plusDays(), plusHours(), minusMonths(), plus(n, ChronoUnit) shift the value — and all of them return a new LocalDateTime. Assign the result: dt = dt.plusHours(1);.

Unlike LocalTime, the time does not wrap around within the day: LocalDateTime.of(2024, 3, 15, 23, 30).plusMinutes(45) gives 2024-03-16T00:15.

Compare with isBefore(), isAfter(), isEqual() or equals(), but not == (it compares references). The class implements Comparable; compare the result of compareTo() with zero, not with -1.

truncatedTo() drops extra precision: truncatedTo(ChronoUnit.DAYS) gives midnight of the same day, truncatedTo(ChronoUnit.MINUTES) drops the seconds. Units longer than a day (MONTHS) throw UnsupportedTemporalTypeException.

4. 

How do you calculate the difference between two LocalDateTime values?

There are two ways:

  • Duration.between(start, end) — a duration in hours, minutes and seconds, for example PT8H30M;
  • ChronoUnit.X.between(start, end) — the number of whole units as a long, for example ChronoUnit.MINUTES.between(start, end) = 510.

Partial units are dropped: from 22:00 on March 15 to 06:30 on March 16, ChronoUnit.DAYS.between returns 0. To check whether the calendar date has changed, compare the dates: Period.between(start.toLocalDate(), end.toLocalDate()) gives P1D. Period.between(start, end) with LocalDateTime arguments does not compile — it accepts only LocalDate.

5. 

What is the difference between LocalDateTime and Instant, and when should you use each?

LocalDateTime is a "wall clock" date and time without a zone (2024-03-15T10:30): the same value in Moscow and in Berlin is a different moment, so on its own it does not identify a point in time. Instant is an exact moment on the UTC time line (2024-03-15T07:30:00Z), the same for everyone.

LocalDateTime knows nothing about clock changes: the time 2024-03-31T02:30, which does not exist in Berlin, is silently shifted to 03:30+02:00 by atZone(), and on the night the clocks go back ChronoUnit.HOURS.between counts 6 hours between 00:00 and 06:00 instead of the real 7.

Choice: LocalDateTime for local values such as "doctor's appointment on March 15 at 10:30", schedules, a "date and time" form field; Instant (or ZonedDateTime/OffsetDateTime) for event timestamps, logs, durations and data exchanged between services.

6. 

How do you convert a LocalDateTime to an Instant or milliseconds and back?

The conversion is impossible without a zone, which is why LocalDateTime has no no-argument toInstant(). You must supply a zone or an offset:

Instant i1 = ldt.atZone(ZoneId.of("Europe/Moscow")).toInstant();
Instant i2 = ldt.toInstant(ZoneOffset.UTC);
long millis = i1.toEpochMilli();
LocalDateTime back = LocalDateTime.ofInstant(i1, ZoneId.of("Asia/Tokyo"));

ldt.toEpochSecond(ZoneOffset.ofHours(3)) returns epoch seconds; the legacy java.util.Date goes through the same Instant: Date.from(ldt.atZone(zone).toInstant()).

Be careful with ZoneId.systemDefault(): on a laptop in Moscow and on a server in UTC it produces moments 3 hours apart. Use the user's zone, and if it is unknown, store the LocalDateTime as is.

Page 1 of 1