LocalDateTime

Su Suriya Ravichandran Updated 14 Nov 2026
6 min read ·Lesson 116 of 133

java.time.LocalDateTime combines a date and a time of day, such as 2026-11-13T21:45, without a time zone. It is a LocalDate and a LocalTime joined together, and supports everything both of them do. It is useful for values that are naturally "wall-clock" readings in a known context: an appointment entered on a form, a timestamp printed on a parking ticket, or a scheduled time inside a system that runs in a single zone. Because it has no zone, it does not identify a single moment worldwide; that distinction is the most important thing to understand about it.

Creating a LocalDateTime

import java.time.*;

LocalDateTime now = LocalDateTime.now();                              // current date-time, default zone
LocalDateTime dt = LocalDateTime.of(2026, 11, 13, 21, 45);            // year, month, day, hour, minute
LocalDateTime withSeconds = LocalDateTime.of(2026, 11, 13, 21, 45, 30);
LocalDateTime parsed = LocalDateTime.parse("2026-11-13T09:30");       // ISO format with 'T'
LocalDateTime combined = LocalDate.of(2026, 11, 13).atTime(LocalTime.NOON);   // 2026-11-13T12:00
LocalDateTime midnight = LocalDate.of(2026, 11, 13).atStartOfDay();           // 2026-11-13T00:00
LocalDateTime fromParts = LocalDateTime.of(LocalDate.of(2026, 11, 13), LocalTime.of(9, 0));

The ISO text form uses a T between the date and the time: 2026-11-13T21:45. A string with a space instead (2026-11-13 21:45) needs a custom formatter to parse.

Reading and Splitting

LocalDateTime dt = LocalDateTime.of(2026, 11, 13, 21, 45);

dt.getYear();            // 2026
dt.getMonth();           // NOVEMBER
dt.getDayOfWeek();       // FRIDAY
dt.getHour();            // 21
dt.toLocalDate();        // 2026-11-13
dt.toLocalTime();        // 21:45

Arithmetic Crosses Day Boundaries Correctly

Unlike LocalTime, which wraps at midnight, LocalDateTime carries over into the next day, month, or year:

dt.plusHours(3);                      // 2026-11-14T00:45: next day
dt.plusMinutes(20).withSecond(5);     // 2026-11-13T22:05:05
dt.minusMonths(11);                   // 2025-12-13T21:45
dt.truncatedTo(ChronoUnit.HOURS);     // 2026-11-13T21:00

The plus, minus, with, and truncatedTo methods all return new objects; the original is unchanged.

Comparing and Measuring

LocalDateTime start = LocalDateTime.of(2026, 11, 13, 21, 45);
LocalDateTime end = start.plusDays(1).plusMinutes(5);

start.isBefore(end);                         // true
Duration.between(start, end);                // PT24H5M
ChronoUnit.HOURS.between(start, end);        // 24
ChronoUnit.MINUTES.between(start, end);      // 1445

Duration.between gives the exact time difference, including spans across midnight. Its toHours(), toMinutesPart(), and similar methods split it into units for display.

The Missing Time Zone

LocalDateTime stores no time zone, and that has two consequences.

It does not represent a unique moment. 2026-11-13T21:45 happens in Chennai about five and a half hours before it happens in London. If a server stores this value for an order placed by a user, there is no way to tell later which moment the order actually happened.

It ignores daylight-saving time. In zones with DST, local clocks skip an hour in spring and repeat an hour in autumn. LocalDateTime arithmetic assumes every day has exactly 24 hours, so durations across a DST change can be off by an hour:

// In New York, clocks jump from 02:00 to 03:00 on 8 March 2026.
LocalDateTime before = LocalDateTime.of(2026, 3, 8, 1, 0);
LocalDateTime after = LocalDateTime.of(2026, 3, 8, 4, 0);
Duration.between(before, after);         // PT3H by the wall clock; only 2 hours actually passed

ZonedDateTime, covered in the next lesson, applies the zone's rules and gives the true elapsed time. India does not observe daylight-saving time, so this issue does not arise with Asia/Kolkata, but software serving users in other countries must account for it.

When to use LocalDateTime

Use LocalDateTime forUse something else for
Wall-clock values in a single, known zone (a local parking system, a shop's till)Events that must be compared across zones (use Instant or ZonedDateTime)
Form input before the user's zone is attachedStored timestamps of when things happened (Instant, OffsetDateTime)
Future appointments where the local time is what matters, stored together with a ZoneIdDurations that must be exact across DST changes (ZonedDateTime)

A common, sound design is to store when something happened as an Instant (UTC) and convert to the user's zone only for display, while storing future local appointments as a LocalDateTime plus a ZoneId, so that the appointment keeps its wall-clock time even if the zone's rules change before it occurs.

Attaching a Zone or Offset

LocalDateTime dt = LocalDateTime.of(2026, 11, 13, 21, 45);

ZonedDateTime zdt = dt.atZone(ZoneId.of("Asia/Kolkata"));      // 2026-11-13T21:45+05:30[Asia/Kolkata]
OffsetDateTime odt = dt.atOffset(ZoneOffset.ofHoursMinutes(5, 30));
Instant instant = zdt.toInstant();                              // 2026-11-13T16:15:00Z

Once a zone is attached, the value becomes a real moment that can be converted, stored, and compared globally.

LocalDateTime and Databases

JDBC 4.2 drivers map SQL TIMESTAMP (without time zone) columns to LocalDateTime, and TIMESTAMP WITH TIME ZONE to OffsetDateTime. When storing moments, prefer a zone-aware column or store UTC values consistently; mixing local timestamps from servers in different zones is a frequent source of hard-to-trace bugs.

Practical Example: Parking Fees

A parking lot runs entirely in local time, so LocalDateTime is a good fit. Parking is free for 15 minutes; after that, every started hour costs ₹40, capped at ₹300 per 24 hours.

import java.time.*;
import java.util.List;

public class Parking {
    static long fee(LocalDateTime in, LocalDateTime out) {
        if (out.isBefore(in)) throw new IllegalArgumentException("exit before entry");
        long minutes = Duration.between(in, out).toMinutes();
        if (minutes <= 15) return 0;                       // grace period
        long hours = (minutes + 59) / 60;                  // every started hour is charged
        long days = hours / 24;
        long rest = hours % 24;
        return days * 300 + Math.min(rest * 40, 300);      // 40 per hour, 300 per day max
    }

    public static void main(String[] args) {
        record Visit(String plate, LocalDateTime in, LocalDateTime out) { }
        List<Visit> visits = List.of(
            new Visit("TN01AB1234", LocalDateTime.of(2026, 11, 13, 9, 0), LocalDateTime.of(2026, 11, 13, 9, 12)),
            new Visit("TN09CD5678", LocalDateTime.of(2026, 11, 13, 9, 0), LocalDateTime.of(2026, 11, 13, 11, 1)),
            new Visit("KA05EF9012", LocalDateTime.of(2026, 11, 13, 21, 45), LocalDateTime.of(2026, 11, 14, 1, 10)),
            new Visit("TN22GH3456", LocalDateTime.of(2026, 11, 13, 8, 0), LocalDateTime.of(2026, 11, 15, 10, 30))
        );
        for (Visit v : visits) {
            Duration stay = Duration.between(v.in(), v.out());
            System.out.printf("%s %s -> %s  %2dh %02dm  fee %d%n", v.plate(), v.in(), v.out(), stay.toHours(), stay.toMinutesPart(), fee(v.in(), v.out()));
        }
    }
}

Output:

TN01AB1234 2026-11-13T09:00 -> 2026-11-13T09:12   0h 12m  fee 0
TN09CD5678 2026-11-13T09:00 -> 2026-11-13T11:01   2h 01m  fee 120
KA05EF9012 2026-11-13T21:45 -> 2026-11-14T01:10   3h 25m  fee 160
TN22GH3456 2026-11-13T08:00 -> 2026-11-15T10:30  50h 30m  fee 720

Duration.between measures each stay correctly even when it crosses midnight (the third vehicle) or spans several days (the fourth). The fee rules then use plain integer arithmetic on the minutes:

  • Grace period. The first stay is within the 15-minute free window.
  • Started hours. The second stay is 2 hours 1 minute, which is 3 started hours, ₹120.
  • Overnight stay. The third stay crosses midnight and is 3 hours 25 minutes, which is 4 started hours, ₹160.
  • Multi-day stay. The fourth stay is 50 hours 30 minutes, which is 51 started hours: two full days at the ₹300 cap plus 3 extra hours at ₹40, totalling ₹720.

The lot operates in one location, which never changes clocks, so local date-times are a safe choice here. A multi-city system would add a ZoneId to each site.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about LocalDateTime and get answers drawn from it.

Signed-in readers only.