Java Date - Date-Time API

LocalDateTime/OffsetDateTime/ZonedDateTime

Overview

Starting with Java SE 8, the Date and Time API was introduced as a new API for handling dates and times. The Date-Time API is included in the java.time package.
The main classes provided by the java.time package are as follows.

  • LocalDateTime/LocalDate/LocalTime: local date and time without timezone offset information
  • OffsetDateTime/OffsetTime: date and time with timezone offset information
  • ZonedDateTime: date and time with information based on timezone and region, such as daylight saving time

In general, Local~ classes are used when timezone offset information is not needed, and Zoned~ classes are used otherwise. Offset~ classes are probably used less often.

now/of/parse Methods of LocalDateTime

The now/of/parse methods create date/time values from strings.

public static LocalDateTime now()
public static LocalDateTime of(int year, int month, int day, int hour, int minute [,int second [,int nano]])
public static LocalDate parse(CharSequence text)
    year: year
    month: month
    day: day
    hour: hour
    minute: minute
    second: second
    nano: nanosecond
    text: date/time string

The java.time package provides Local/Offset/Zoned family classes according to purpose, and these methods are used in the same way to create objects. Use the now method to display the current time. The of method creates an object by specifying year, month, day, hour, minute, and second. You can also use the parse method to create an object from a date/time string.

package com.devkuma.basic.datetime;

import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class TimeCreate {
    public static void main(String[] args) {
        LocalDateTime local = LocalDateTime.now();
        System.out.println(local);
        // Result: 2022-09-05T12:03:34.123041

        OffsetDateTime offset = OffsetDateTime.of(
                2022, 9, 5, 12, 3, 29, 0, ZoneOffset.of("+09:00"));
        System.out.println(offset);
        // Result: 2022-09-05T12:03:29+09:00

        ZonedDateTime zoned = ZonedDateTime.parse("2022-09-05T12:03:29+09:00[Asia/Seoul]");
        System.out.println(zoned);
        // Result: 2022-09-05T12:03:29+09:00[Asia/Seoul]
    }
}

Result:

2022-09-05T12:03:34.123041
2022-09-05T12:03:29+09:00
2022-09-05T12:03:29+09:00[Asia/Seoul]

You can also access each date/time element from each object with the following methods.

Methods for accessing each date/time element

Method Overview
getYear Year
getMonth Month type
getMonthValue Month (1-12)
getDayOfMonth Day
getDayOfWeek Day of week
getDayOfYear Day of year
getHour Hour
getMinute Minute
getSecond Second
getNano Nanosecond

between Method

The between method gets the difference between date/time values.

public static Period between(LocalDate start, LocalDate end) // Period
public static Duration between(Temporal start, Temporal end) // Duration
    start: start date/time
    end: end date/time

You can use the Period/Duration#between method to get the time difference between date/time objects. Period represents a date interval, and Duration represents a time interval.

  • Temporal is a common interface for Local/Offset/Zoned family classes.

The following example gets the difference between two prepared date/time values with the Period/Duration#between method.

TimeBetween.java

package com.devkuma.basic.datetime;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.Period;

public class TimeBetween {
    public static void main(String[] args) {
        LocalDateTime local1 = LocalDateTime.of(
                2021, 1, 1, 3, 30, 0, 0);
        LocalDateTime local2 = LocalDateTime.of(
                2022, 9, 5, 12, 14, 30, 0);
        System.out.println(local1); // Result: 2021-01-01T03:30
        System.out.println(local2); // Result: 2022-09-05T12:14:30

        Period period = Period.between(local1.toLocalDate(), local2.toLocalDate());
        System.out.println("날짜 차이: " + period);   // Result: 날짜 차이: P1Y8M4D

        System.out.println("날짜 차이: " +
                period.getYears() + "년 " + period.getMonths() + "월 " +
                period.getDays() + "일"); // Result: 날짜 차이: 1년 8월 4일

        Duration duration = Duration.between(local1, local2);
        System.out.println("시간 차이: " + duration);
        // Result: 시간 차이: PT14696H44M30S

        System.out.println("시간 차이: " + duration.toHours() + "시간");
        // Result: 시간 차이: 14696시간

        System.out.println("시간 차이: " + duration.toMinutes() + "분");
        // Result: 시간 차이: 881804분

        System.out.println("시간 차이: " + duration.getSeconds() + "초");
        // Result: 시간 차이: 52908270초
    }
}

Result:

2021-01-01T03:30
2022-09-05T12:14:30
날짜 차이: P1Y8M4D
날짜 차이: 1년 8월 4일
시간 차이: PT14696H44M30S
시간 차이: 14696시간
시간 차이: 881804분
시간 차이: 52908270초

To get the number of days or hours from a Period/Duration object, use the following methods.

Main methods of the Period/Duration classes

Class Method Overview
Period getYears Number of years
getMonths Number of months
getDays Number of days
Duration toDays Number of days
toHours Number of hours
toMinutes Number of minutes
toMillis Number of milliseconds
toNanos Number of nanoseconds

Calculating Date and Time Data

public LocalDateTime plus(long value, TemporalUnit unit)
public LocalDateTime minus(long value, TemporalUnit unit)
    value: increment or decrement
    unit: unit

You can use the plus/minus methods to add and subtract date/time elements. The unit argument specifies the unit to add or subtract with constants of ChronoUnit, an implementation class of the TemporalUnit interface.

Main constants of the TemporalUnit interface

Constant Overview
YEARS Years
MONTHS Months
DAYS Days
WEEKS Weeks
HOURS Hours
MINUTES Minutes
SECONDS Seconds
MILLIS Milliseconds
NANOS Nanoseconds

The following example gets the date 3 months later and 10 days earlier from a prepared date.

package com.devkuma.basic.datetime;

import java.time.LocalDateTime;

public class TimePlus {
    public static void main(String[] args) {
        LocalDateTime local = LocalDateTime.parse("2022-09-05T12:30");
        System.out.println(local);  // Result: 2022-09-05T12:30
        System.out.println(local.plusMonths(3));    // Result: 2022-12-05T12:30
        System.out.println(local.minusDays(10));    // Result: 2022-08-26T12:30
    }
}

Result:

2022-09-05T12:30
2022-12-05T12:30
2022-08-26T12:30

The plus/minus methods also provide specialized methods for each date/time element, as follows.

Methods for adding/subtracting date/time

Method Overview
plusYears/minusYears Years
plusMonths/minusMonths Months
plusDays/minusDays Days
plusWeeks/minusWeeks Weeks
plusHours/minusHours Hours
plusMinutes/minusMinutes Minutes
plusSeconds/minusSeconds Seconds
plusNanos/minusNanos Nanoseconds

Converting Between Date/Calendar Classes and Date-Time API Classes

public static Date from(Instant instant) // Date
public Instant toInstant() // Date/Calendar
public static LocalDateTime ofInstant(Instant instant, ZoneId zone) // XxxxxDateTime
    instant: instant to convert

Even though the new Date-Time API has been introduced, it is not realistic to suddenly unify all code under the Date-Time API. For a while, it will be used together with the existing java.util package. Therefore, existing Date/Calendar classes provide methods for converting to and from the Date-Time API.
The Date#from method creates a Date object from a given Instant object. Instant is a class that holds date/time as elapsed time since January 1, 1970. Date/time classes in the Date-Time API each provide a toInstant method so that an Instant object can be created, and passing it to the from method creates a Date object.

  • The Calendar class does not have a method corresponding to Date#from. A Calendar object is created from the generated Date object.

The Calendar/Date classes also provide the toInstant method. You can pass the created Instant object to the ofInstant method of the LocalDateTime/OffsetDateTime/ZonedDateTime classes to create each corresponding object.

The following example converts a LocalDateTime object to a Date object, and a Calendar object to a LocalDateTime object.

package com.devkuma.basic.datetime;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Calendar;
import java.util.Date;

public class TimeTrans {
    public static void main(String[] args) {
        LocalDateTime local = LocalDateTime.now();
        System.out.println(local);  // Result: 2022-09-05T14:32:05.526238

        Instant instant = local.toInstant(ZoneOffset.of("+09:00"));
        Date date = Date.from(instant);
        System.out.println(date);   // Result: Mon Sep 05 14:32:05 KST 2022

        Calendar cal = Calendar.getInstance();
        Instant instant2 = cal.toInstant();
        LocalDateTime local2 = LocalDateTime.ofInstant(instant2, ZoneId.of("Asia/Seoul"));
        System.out.println(local2); // Result: 2022-09-05T14:32:05.542
    }
}

Result:

2022-09-05T14:32:05.526238
Mon Sep 05 14:32:05 KST 2022
2022-09-05T14:32:05.542

How to Convert from String to LocalDate/LocalDateTime

When converting a String to java.time.LocalDate, use LocalDate.parse and DateTimeFormatter to convert the date string.
When converting a String to java.time.LocalDateTime, create a LocalDate from the string and pass it together with LocalTime as arguments.

package com.devkuma.basic.datetime;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class StringConvent {
    public static void main(String[] args) {
        String strDate = "2022/12/12";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");

        LocalDate localDate = LocalDate.parse(strDate, dateTimeFormatter);
        System.out.println(localDate);

        LocalDateTime ldt = LocalDateTime.of(localDate, LocalTime.of(0, 0));
        System.out.println(ldt);
    }
}

Result:

2022-12-12
2022-12-12T00:00

If the date string is in a format such as 2022/12/12, the Format specification can be replaced with DateTimeFormatter.ISO_DATE. DateTimeFormatter.ISO_DATE declares yyyy-MM-dd as a constant.