Java LocalDateTime Explained: Basics, Formatting, Parsing, and Practical Usage

目次

1. Target Audience and What You Will Learn

Have you ever struggled with how to use the LocalDateTime class when working with dates and times in Java? This article is designed for everyone from Java beginners to engineers actively developing enterprise systems, and it carefully explains everything from the fundamentals of LocalDateTime to practical, real-world usage.

What You Will Gain from This Article

  • Understand the basic structure and characteristics of LocalDateTime
  • Learn how to create, convert, format, and perform arithmetic on dates and times through concrete examples
  • Understand the differences between LocalDateTime and legacy APIs such as Date and Calendar, and when to use each
  • Learn how to handle common use cases such as database integration and frequently encountered errors
  • Avoid common pitfalls in development and handle date-time logic efficiently and safely

Recommended for the Following Readers

  • Developers who want to handle dates and times in Java safely and cleanly
  • Those who want to master LocalDateTime comprehensively
  • Engineers looking for best practices in date-time management for system design and development
  • Developers working with databases such as MySQL or PostgreSQL
  • Anyone struggling with migration from legacy APIs (Date / Calendar)

By reading this article, you will gain the knowledge and confidence to stop worrying about date and time handling in Java. Let’s start by explaining the basics of LocalDateTime and how it differs from other commonly compared classes.

2. What Is LocalDateTime? Basics and Differences from Other Classes

Basic Overview of LocalDateTime

LocalDateTime is part of the modern date and time API introduced in Java 8 under the java.time package. Its key feature is that it can handle both date and time simultaneously, storing values down to year, month, day, hour, minute, second, and nanoseconds.

Unlike legacy APIs such as java.util.Date and Calendar, LocalDateTime does not contain time zone information. This makes it ideal for representing a simple local date and time, such as a scheduled event or record like “July 10, 2025, 15:30:00,” where time zones are irrelevant.

Another important characteristic is that LocalDateTime is immutable and thread-safe. Any modification returns a new instance, making it safe to use in multi-threaded environments.

Differences from Legacy APIs and Other Date-Time Classes

Java provides multiple date-time classes, each serving a different purpose. The table below summarizes their differences and typical use cases.

ClassTime ZoneManaged DataMain Use Case
LocalDateTimeNoDate and timeRepresenting local date-time values
LocalDateNoDate onlyWhen only the date is needed
LocalTimeNoTime onlyWhen only the time is needed
ZonedDateTimeYesDate, time, and time zoneWhen explicit time zone handling is required
OffsetDateTimeYes (e.g., +09:00)Date, time, and offsetAPIs or systems sensitive to time differences
Date / CalendarVariesDate and timeLegacy APIs (not recommended today)

Key Points

  • Use ZonedDateTime or OffsetDateTime when time zones matter
  • Use LocalDate or LocalTime when you only need date or time
  • Use LocalDateTime when managing local date and time without time zones

Typical Use Cases for LocalDateTime

  • Scheduling systems and task deadlines
  • Logging and audit records in local time
  • Integration with database DATETIME columns

When working across servers or users in different regions, time zone handling becomes critical. In such cases, consider using ZonedDateTime instead.

3. How to Create LocalDateTime Instances (With Code Examples)

When starting with LocalDateTime, one of the first things to learn is how to create instances. This section introduces the most commonly used creation methods with practical examples.

3-1. Getting the Current Date and Time (now)

The simplest usage is retrieving the current local date and time. While no time zone is included, the value is based on the system’s default time zone.

import java.time.LocalDateTime;

LocalDateTime now = LocalDateTime.now();
System.out.println(now); // Example: 2025-07-10T15:30:45.123

3-2. Creating a Specific Date and Time (of)

To create a specific date and time, use the of() method. You can specify values down to seconds and nanoseconds (which are optional).

LocalDateTime dateTime = LocalDateTime.of(2025, 7, 10, 15, 30, 0);
System.out.println(dateTime); // 2025-07-10T15:30

3-3. Creating from a String (parse)

LocalDateTime can also be created from strings in ISO-8601 format (e.g., "2025-07-10T15:30:00") or custom formats.

Using the standard ISO format:

LocalDateTime parsed = LocalDateTime.parse("2025-07-10T15:30:00");
System.out.println(parsed); // 2025-07-10T15:30

Using a custom format (with DateTimeFormatter):

import java.time.format.DateTimeFormatter;

String input = "2025/07/10 15:30:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime parsedCustom = LocalDateTime.parse(input, formatter);
System.out.println(parsedCustom); // 2025-07-10T15:30

3-4. Common Error: DateTimeParseException

A frequently encountered error when using parse() is DateTimeParseException. The main cause is a mismatch between the input string format and the formatter.

Example:

LocalDateTime.parse("2025/07/10 15:30:00");
// Error: not in ISO-8601 format

Solution:

  • Always specify a DateTimeFormatter if the format is not ISO-8601.
  • Validate input strings in advance whenever possible.

Summary

  • Use LocalDateTime.now() for the current date and time
  • Use of() to create a specific date-time
  • Use parse() with DateTimeFormatter for strings
  • Ensure format consistency to avoid parsing errors

4. Formatting LocalDateTime and Converting to Strings

When handling date and time data in Java, you will often need to pay attention to display formats and input/output formats. While LocalDateTime outputs an ISO-8601 format by default (e.g., 2025-07-10T15:30:00), real-world applications often require custom formatting. This section explains how to format LocalDateTime values and what to watch out for.

4-1. Default Output and ISO-8601 Format

When you output a LocalDateTime instance directly using System.out.println(), it is displayed in the ISO-8601 format YYYY-MM-DDTHH:MM:SS. The T character represents the separator between date and time, as defined by the ISO standard.

LocalDateTime now = LocalDateTime.now();
System.out.println(now); // Example: 2025-07-10T15:30:45.123

4-2. Converting to Custom Formats (Using DateTimeFormatter)

In business applications and database integration, you often need custom or region-specific formats. In such cases, use the DateTimeFormatter class.

Example: A commonly used pattern in Japan

import java.time.format.DateTimeFormatter;

LocalDateTime dateTime = LocalDateTime.of(2025, 7, 10, 15, 30, 0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
String formatted = dateTime.format(formatter);

System.out.println(formatted); // 2025/07/10 15:30:00

You can freely define other formats, such as:

  • "yyyy年MM月dd日 HH時mm分ss秒"
  • "yyyyMMdd_HHmmss"

4-3. When the Output Contains “T” and When It Does Not

  • The “T” appears when using toString() or DateTimeFormatter.ISO_LOCAL_DATE_TIME.
  • The “T” can be removed by specifying a custom format pattern.

Example: Output without “T”

DateTimeFormatter noT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
System.out.println(dateTime.format(noT)); // 2025-07-10 15:30:00

4-4. Converting Strings Back to LocalDateTime

As mentioned in Section 3, converting a string with a custom format back into LocalDateTime requires using DateTimeFormatter with parse().

String input = "2025/07/10 15:30:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime parsed = LocalDateTime.parse(input, formatter);
System.out.println(parsed); // 2025-07-10T15:30

Summary

  • Default output follows ISO-8601 (with “T”)
  • Use DateTimeFormatter for custom output formats
  • Use formatters to safely parse strings into LocalDateTime
  • Flexibly customize formats to meet business and integration requirements

5. Adding, Subtracting, and Comparing Dates and Times (Common in Practice)

In real-world applications, it is common to perform operations such as “calculate a date several days later” or “compare two date-time values.” LocalDateTime provides intuitive APIs for these operations.

5-1. Adding and Subtracting Date-Time Values (plus / minus)

LocalDateTime offers a rich set of methods for adding and subtracting time units. Below are some commonly used examples.

Examples of addition:

LocalDateTime base = LocalDateTime.of(2025, 7, 10, 15, 30, 0);
LocalDateTime plusDays = base.plusDays(5);        // 5 days later
LocalDateTime plusHours = base.plusHours(3);      // 3 hours later
LocalDateTime plusMonths = base.plusMonths(1);    // 1 month later

System.out.println(plusDays);   // 2025-07-15T15:30
System.out.println(plusHours);  // 2025-07-10T18:30
System.out.println(plusMonths); // 2025-08-10T15:30

Examples of subtraction:

LocalDateTime minusDays = base.minusDays(2);        // 2 days earlier
LocalDateTime minusMinutes = base.minusMinutes(45); // 45 minutes earlier

System.out.println(minusDays);    // 2025-07-08T15:30
System.out.println(minusMinutes); // 2025-07-10T14:45

5-2. Comparing Date-Time Values (isBefore, isAfter, equals)

To determine whether one date-time is before, after, or equal to another, use the following methods.

LocalDateTime a = LocalDateTime.of(2025, 7, 10, 10, 0, 0);
LocalDateTime b = LocalDateTime.of(2025, 7, 10, 15, 0, 0);

System.out.println(a.isBefore(b)); // true
System.out.println(a.isAfter(b));  // false
System.out.println(a.equals(b));   // false

5-3. Calculating Differences (Duration vs Period)

When you need to calculate the difference between two date-time values, choose between Duration and Period depending on what you want to measure.

  • Duration: For time-based differences (seconds, minutes, hours)
  • Period: For date-based differences (years, months, days)

Example: Duration (time difference)

import java.time.Duration;

LocalDateTime start = LocalDateTime.of(2025, 7, 10, 10, 0, 0);
LocalDateTime end = LocalDateTime.of(2025, 7, 10, 15, 0, 0);

Duration duration = Duration.between(start, end);
System.out.println(duration.toHours());   // 5
System.out.println(duration.toMinutes()); // 300

Example: Period (date difference)

import java.time.Period;

LocalDateTime dateTime1 = LocalDateTime.of(2025, 7, 10, 0, 0, 0);
LocalDateTime dateTime2 = LocalDateTime.of(2025, 8, 5, 0, 0, 0);

// Convert to LocalDate before calculating the difference
Period period = Period.between(dateTime1.toLocalDate(), dateTime2.toLocalDate());
System.out.println(period.getMonths()); // 0
System.out.println(period.getDays());   // 26

Summary

  • Use plus and minus for easy arithmetic operations
  • Use isBefore and isAfter to compare date-time values
  • Use Duration for time-based differences and Period for date-based differences
  • Combining these APIs keeps business logic clean and readable

6. Converting LocalDateTime with Other Classes and Database Types

When integrating with business systems or existing applications, converting LocalDateTime to other date-time classes or database types is very common. This section summarizes frequently used conversion patterns and important points to note.

6-1. Converting Between LocalDate and LocalTime

While LocalDateTime represents both date and time, there are many cases where you need to handle only the date or only the time.

LocalDateTime → LocalDate / LocalTime

LocalDateTime dateTime = LocalDateTime.of(2025, 7, 10, 15, 30, 0);

LocalDate date = dateTime.toLocalDate();
LocalTime time = dateTime.toLocalTime();

System.out.println(date); // 2025-07-10
System.out.println(time); // 15:30

LocalDate / LocalTime → LocalDateTime

LocalDate date = LocalDate.of(2025, 7, 10);
LocalTime time = LocalTime.of(15, 30);

LocalDateTime dateTime = LocalDateTime.of(date, time);
System.out.println(dateTime); // 2025-07-10T15:30

6-2. Converting with java.util.Date, Calendar, and java.sql.Timestamp

When working with legacy APIs or JDBC, you may need to convert between LocalDateTime and older date-time types such as Date or Timestamp.

LocalDateTime → java.sql.Timestamp

import java.sql.Timestamp;
import java.time.LocalDateTime;

LocalDateTime dateTime = LocalDateTime.now();
Timestamp timestamp = Timestamp.valueOf(dateTime);
System.out.println(timestamp); // Example: 2025-07-10 15:30:00.123

java.sql.Timestamp → LocalDateTime

Timestamp timestamp = Timestamp.valueOf("2025-07-10 15:30:00");
LocalDateTime dateTime = timestamp.toLocalDateTime();
System.out.println(dateTime); // 2025-07-10T15:30

Converting java.util.Date or Calendar requires an intermediate Instant

Date date = new Date();
LocalDateTime dateTime =
    date.toInstant()
        .atZone(ZoneId.systemDefault())
        .toLocalDateTime();

6-3. Mapping to Database DATETIME Types (MySQL / PostgreSQL)

LocalDateTime works very well with DATETIME columns in MySQL and PostgreSQL. Using JDBC drivers, you can convert smoothly via setTimestamp and getTimestamp.

  • MySQL / PostgreSQL DATETIME ↔ Java LocalDateTime or java.sql.Timestamp
  • When reading: use getTimestamp()toLocalDateTime()
  • When writing: convert with Timestamp.valueOf(LocalDateTime) and use setTimestamp()

Important: Be careful with time zone management

  • DATETIME columns in MySQL and PostgreSQL do not store time zone information.
  • It is critical to keep a consistent time zone policy within the application.
  • If strict time zone control is required, consider TIMESTAMP WITH TIME ZONE or using ZonedDateTime.

6-4. Converting with ZonedDateTime and OffsetDateTime

When time zone information is required, conversions between LocalDateTime and ZonedDateTime are commonly used.

LocalDateTime localDateTime = LocalDateTime.now();
ZoneId zone = ZoneId.of("Asia/Tokyo");

ZonedDateTime zonedDateTime = localDateTime.atZone(zone);
System.out.println(zonedDateTime); // 2025-07-10T15:30+09:00[Asia/Tokyo]

LocalDateTime backToLocal = zonedDateTime.toLocalDateTime();
System.out.println(backToLocal); // 2025-07-10T15:30

Summary

  • LocalDateTime can be easily converted to and from other date-time classes and database types
  • JDBC integration works smoothly via Timestamp
  • Use ZonedDateTime or OffsetDateTime when time zone handling is required
  • Ensure time zone consistency when integrating with databases

7. Practical Use Cases and Quick Reference by Scenario

This section organizes real-world use cases for LocalDateTime and helps you choose the appropriate class depending on the situation.

7-1. Common Practical Use Cases

(1) Task and Schedule Management Systems

LocalDateTime is ideal when managing schedules and deadlines that require both date and time. It allows intuitive handling of task start and end times.

LocalDateTime deadline =
    LocalDateTime.of(2025, 7, 31, 23, 59, 59);

(2) Attendance and Time Tracking

Clock-in and clock-out records require both date and time. Integration with database DATETIME columns is straightforward.

LocalDateTime clockIn = LocalDateTime.now();

(3) Logging and Audit Trails

System logs and error histories often record event timestamps using LocalDateTime. It is suitable when time zone adjustments are unnecessary or logs are internal to the application.

7-2. Quick Reference Table by Use Case

Use CaseRecommended ClassReason
Store local date and timeLocalDateTimeBest choice when time zones are not required
Date onlyLocalDateCalendars, birthdays, etc.
Time onlyLocalTimeAlarms, business hours
Explicit time zone managementZonedDateTimeMulti-region systems
Use UTC or offsetsOffsetDateTimeAPIs and external integrations

7-3. When You Need a Time Zone and When You Do Not

Typical cases where a time zone is not required

  • Date-time values used only within the application
  • Single-location systems (e.g., domestic-only services)

Typical cases where a time zone is required

  • Systems involving multiple regions or international users
  • Servers running in different time zones
  • Applications that display times differently based on user location

Decision guideline

Ask yourself: “Does this date-time represent an absolute moment in time?” If yes, use ZonedDateTime or OffsetDateTime.

7-4. Simple Class Selection Flow

  1. Does the date-time require time zone awareness?
  • Yes → ZonedDateTime or OffsetDateTime
  • No → Go to step 2
  1. Do you need date only, time only, or both?
  • Date only → LocalDate
  • Time only → LocalTime
  • Date and time → LocalDateTime

Summary

  • LocalDateTime is ideal for managing local date and time without time zones
  • Choosing the right class simplifies system design and maintenance
  • Clearly understanding requirements helps avoid future bugs and inconsistencies

8. Common Errors, Troubleshooting, and Solutions

When using LocalDateTime, developers often encounter recurring errors or sources of confusion. This section summarizes common issues and their solutions in a Q&A format, allowing you to respond quickly when problems arise.

Q1. DateTimeParseException Occurs

Cause

  • This exception occurs when the string passed to LocalDateTime.parse() does not match the expected format.
  • Strings that are not in ISO-8601 format (e.g., "2025-07-10T15:30:00") require a DateTimeFormatter.

Solution

  • Always verify that the format matches and use DateTimeFormatter when necessary.
String input = "2025/07/10 15:30:00";
DateTimeFormatter formatter =
    DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime.parse(input, formatter); // OK

Q2. Beware of NullPointerException

Cause

  • Calling methods on a null LocalDateTime reference.

Solution

  • Check for null values before use.
  • Wrapping values in Optional can also be effective.

Q3. Incorrect Time Zone Handling

Cause

  • LocalDateTime does not store time zone information, so changes in system or database time zones can cause unexpected results.

Solution

  • Unify server and database time zone settings.
  • Use ZonedDateTime or OffsetDateTime when time zone accuracy is required.

Q4. Date-Time Values Shift When Integrating with Databases

Cause

  • Mismatches between database column types or time zone settings and Java application settings.

Solution

  • Clearly define the time zone basis when using DATETIME and LocalDateTime.
  • Consider using TIMESTAMP WITH TIME ZONE or ZonedDateTime when strict accuracy is required.

Q5. Loss of Precision (Milliseconds / Nanoseconds)

Cause

  • Some JDBC drivers or databases support only millisecond precision, truncating nanoseconds.

Solution

  • Confirm whether this precision loss is acceptable in your system requirements.
  • Use alternative handling if nanosecond precision is mandatory.

Q6. Errors When Converting from Legacy APIs (Date, Calendar)

Cause

  • Attempting to convert Date or Calendar directly into LocalDateTime.

Solution

  • Always convert through Instant and ZoneId.
Date date = new Date();
LocalDateTime dateTime =
    date.toInstant()
        .atZone(ZoneId.systemDefault())
        .toLocalDateTime();

Practical Development Tips

  • Pay attention to formatting, time zones, and null checks to prevent most issues
  • Always verify type and configuration consistency when integrating with databases or other systems
  • When errors occur, carefully read exception messages and review input values, conversion logic, and environment settings

9. Frequently Asked Questions (FAQ)

This section answers frequently asked questions about LocalDateTime that commonly arise in real-world development scenarios. Use it as a quick reference when troubleshooting or designing systems.

Q1. Can LocalDateTime handle time zones?

No. LocalDateTime does not store time zone information. If you need to manage absolute moments in time, use ZonedDateTime or OffsetDateTime.

Q2. What is the safest way to migrate from Date / Calendar to LocalDateTime?

You cannot convert Date or Calendar directly. Always convert via Instant and ZoneId.

Date date = new Date();
LocalDateTime dateTime =
    date.toInstant()
        .atZone(ZoneId.systemDefault())
        .toLocalDateTime();

Q3. Why does the output sometimes contain “T”?

The “T” character is the ISO-8601 standard separator. It appears when using toString() or DateTimeFormatter.ISO_LOCAL_DATE_TIME. To remove it, specify a custom format pattern.

Q4. What should I watch out for when storing values in a database?

Database DATETIME columns do not store time zone information. Ensure that the application consistently uses a single time zone. If strict accuracy is required, consider using TIMESTAMP WITH TIME ZONE or ZonedDateTime.

Q5. How much precision does LocalDateTime support?

LocalDateTime supports nanosecond precision. However, many databases and JDBC drivers only support milliseconds, which may truncate finer precision.

Q6. Is LocalDateTime affected by daylight saving time (DST)?

No. LocalDateTime itself does not apply daylight saving adjustments. Use ZonedDateTime if DST handling is required.

Q7. What should I use if I only need a date or time?

Use LocalDate for dates only and LocalTime for times only. LocalDateTime is ideal when both are required.

Q8. How should I handle exceptions?

Carefully read exception messages and check:

  • Whether string formats are correct
  • Whether null or invalid values are present
  • Whether conversion steps are implemented correctly

10. Summary and Reference Links

This article has covered everything from the basics of LocalDateTime to practical usage, common pitfalls, and frequently asked questions. Below is a concise summary and helpful references for further learning.

10-1. Key Takeaways for Using LocalDateTime Correctly

  • LocalDateTime is a safe and intuitive class for managing local date and time without time zones. It supports arithmetic operations, formatting, comparison, and parsing with ease.
  • Select the appropriate date-time class based on system requirements.
  • Use LocalDate for dates only
  • Use LocalTime for times only
  • Use ZonedDateTime or OffsetDateTime when time zones matter
  • Pay close attention to time zones and formats when integrating with databases or external systems.
  • Understanding common errors in advance helps prevent issues. Refer to the FAQ and troubleshooting sections for quick resolution.

10-2. Reference Links and Documentation

10-3. Final Notes for Developers

With the knowledge from this article, you should no longer struggle with LocalDateTime usage. When new requirements arise, always refer to official documentation and trusted technical resources to stay up to date.

By applying correct concepts and best practices, you can make Java date-time handling safer, cleaner, and more maintainable in real-world systems.