How do I use atTime() method of Java Date-Time API?

The atTime() method belongs to the LocalDate class in the Java Date-Time API, not the Date class. This method combines this date with a time to create a LocalDateTime.

Here’s an example:

package org.kodejava.datetime;

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

public class AtTimeExample {
    public static void main(String[] args) {
        // Create a LocalDate instance
        LocalDate date = LocalDate.of(2023, 1, 23);

        // Create a LocalTime instance
        // 24-hour clocks
        LocalTime time = LocalTime.of(13, 45);

        // Use atTime() to combine date and time into a LocalDateTime
        LocalDateTime dateTime = date.atTime(time);

        System.out.println(dateTime);
    }
}

Output:

2023-01-23T13:45

In this example, a LocalDate and a LocalTime are combined into a LocalDateTime using the atTime() method.

The LocalDate class also has an overloaded atTime method that takes the hour and minute directly, instead of a LocalTime instance.

Here’s an example where we set 14 hours and 30 minutes directly.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.LocalDateTime;

public class AtTimeOtherExample {
    public static void main(String[] args) {
        // Create a LocalDate instance
        LocalDate date = LocalDate.of(2023, 1, 23);

        // Use atTime() to combine date and hour and minute into a
        // LocalDateTime
        LocalDateTime dateTime = date.atTime(14, 30);

        System.out.println(dateTime);
    }
}

Output:

2023-01-23T14:30

In this example, 14:30 (in 24-hour clock) is directly passed into atTime. There is another version of atTime() that takes hrs, min, and sec. That would look like this:

// include seconds
LocalDateTime dateTime = date.atTime(14, 30, 20);
// include nano seconds
LocalDateTime dateTime = date.atTime(14, 30, 20, 200); 

These are all the overloaded versions of atTime() in LocalDate.

Remember, LocalDate, LocalTime, LocalDateTime and others from Java Date-Time API are designed to replace the old Date and Calendar classes from java.util package. They are more consistent, easier to understand and use.

How do I convert datetime string with optional part to a date object?

Since JDK 8, we can create a datetime formatter / parser pattern that can have optional sections. When parsing a datetime string that contains optional values, for example, a date without time part or a datetime without second part, we can create a parsing pattern wrapped within the [] symbols. The [ character is the optional section start symbol, and the ] character is the optional section end symbol. The pattern inside this symbol will be considered as an optional value.

We can use the java.time.format.DateTimeFormatter class to parse the string of datetime or format the datetime object, and use it with the new Java time API classes such as java.time.LocalDate or java.time.LocalDateTime to convert the string into respective LocalDate or LocalDateTime object as show in the code snippet below.

package org.kodejava.datetime;

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

public class DateTimeParseOptionalParts {
    public static final String OPT_TIME_PATTERN = "yyyy-MM-dd[ HH:mm[:ss]]";
    public static final String OPT_SECOND_PATTERN = "yyyy-MM-dd HH:mm[:ss]";

    public static void main(String[] args) {
        DateTimeFormatter optTimeFormatter = DateTimeFormatter.ofPattern(OPT_TIME_PATTERN);
        LocalDate date1 = LocalDate.parse("2023-08-28", optTimeFormatter);
        LocalDate date2 = LocalDate.parse("2023-08-28 17:15", optTimeFormatter);
        LocalDate date3 = LocalDate.parse("2023-08-28 17:15:30", optTimeFormatter);
        System.out.println("date1 = " + date1);
        System.out.println("date2 = " + date2);
        System.out.println("date3 = " + date3);

        DateTimeFormatter optSecondFormatter = DateTimeFormatter.ofPattern(OPT_SECOND_PATTERN);
        LocalDateTime datetime1 = LocalDateTime.parse("2023-08-28 17:15", optSecondFormatter);
        LocalDateTime datetime2 = LocalDateTime.parse("2023-08-28 17:15:30", optSecondFormatter);
        System.out.println("datetime1 = " + datetime1);
        System.out.println("datetime2 = " + datetime2);
    }
}

Here are the outputs of the code snippet above:

date1 = 2023-08-28
date2 = 2023-08-28
date3 = 2023-08-28
datetime1 = 2023-08-28T17:15
datetime2 = 2023-08-28T17:15:30

How do I modified the value of LocalDate and LocalTime object?

The easiest way to modify the value of a LocalDate, LocalTime or LocalDateTime object is to use the with() method of the corresponding object. These methods will return a modified version of the object, it doesn’t change the attribute of the original object. All the methods, like withYear(), withDayOfMonth() or the with(ChronoField) of the LocalDate object will return a new object with the modified attribute.

With the LocalTime object you can use the withHour(), withMinute(), withSecond() or the more generic with(ChronoField) method to modified the attribute of a LocalTime object. You can also modified a LocalDateTime object using these with() method. Let’s see the example in the code snippet below.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

public class ManipulatingDateTime {
    public static void main(String[] args) {
        LocalDate date1 = LocalDate.of(2021, 4, 21);
        System.out.println("date1 = " + date1);
        LocalDate date2 = date1.withYear(2020);
        System.out.println("date2 = " + date2);
        LocalDate date3 = date2.withDayOfMonth(10);
        System.out.println("date3 = " + date3);
        LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 12);
        System.out.println("date4 = " + date4);

        LocalTime time1 = LocalTime.of(1, 5, 10);
        System.out.println("time1 = " + time1);
        LocalTime time2 = time1.withHour(6);
        System.out.println("time2 = " + time2);
        LocalTime time3 = time2.withMinute(45);
        System.out.println("time3 = " + time3);
        LocalTime time4 = time3.with(ChronoField.SECOND_OF_MINUTE, 25);
        System.out.println("time4 = " + time4);

        LocalDate now1 = LocalDate.now();
        System.out.println("now1 = " + now1);
        LocalDate now2 = now1.plusWeeks(1);
        System.out.println("now2 = " + now2);
        LocalDate now3 = now2.minusMonths(2);
        System.out.println("now3 = " + now3);
        LocalDate now4 = now3.plus(15, ChronoUnit.DAYS);
        System.out.println("now4 = " + now4);
    }
}

The output of this code snippet are:

date1 = 2021-04-21
date2 = 2020-04-21
date3 = 2020-04-10
date4 = 2020-12-10
time1 = 01:05:10
time2 = 06:05:10
time3 = 06:45:10
time4 = 06:45:25
now1 = 2021-11-22
now2 = 2021-11-29
now3 = 2021-09-29
now4 = 2021-10-14

These with() methods is the counterpart of the get() methods. Where the get() methods will give you the value of the corresponding LocalDate or LocalTime attribute, the with() method will change the attribute value and return a new object. It didn’t call set because the object is immutable, which means it value cannot be changed.

While with the with() method you can change the value of date time attribute in an absolute way using the plus() or minus() method can help you change the date and time attribute in a relative way. The plus() and minus() method allows you to move a Temporal back or forward a give amount of time, defined by a number plus a TemporalUnit, in this case we use the ChronoUnit enumeration which implements this interface.

How to convert java.time.LocalDate to java.util.Date?

The following code snippet demonstrate how to convert java.time.LocalDate to java.util.Date and vice versa. In the first part of the code snippet we convert LocalDate to Date and back to LocalDate object. On the second part we convert LocalDateTime to Date and back to LocalDateTime object.

package org.kodejava.datetime;

import java.time.*;
import java.util.Date;

public class LocalDateToDate {
    public static void main(String[] args) {
        // Convert java.time.LocalDate to java.util.Date and back to
        // java.time.LocalDate
        LocalDate localDate = LocalDate.now();
        System.out.println("LocalDate = " + localDate);

        Date date1 = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        System.out.println("Date      = " + date1);

        localDate = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        System.out.println("LocalDate = " + localDate);
        System.out.println();

        // Convert java.time.LocalDateTime to java.util.Date and back to
        // java.time.LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("LocalDateTime = " + localDateTime);

        Date date2 = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        System.out.println("Date          = " + date2);

        localDateTime = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        System.out.println("LocalDateTime = " + localDateTime);
    }
}

The result of the code snippet:

LocalDate = 2021-11-20
Date      = Sat Nov 20 00:00:00 CST 2021
LocalDate = 2021-11-20

LocalDateTime = 2021-11-20T18:25:05.706380200
Date          = Sat Nov 20 18:25:05 CST 2021
LocalDateTime = 2021-11-20T18:25:05.706

How to find the difference between two LocalDateTime objects?

In the previous post, How do I find the difference between two times?, we get the difference between two LocalTime objects in seconds measurement. In this example we will get the difference between two LocalDateTime objects and get the difference between these objects in years, months, days, hours, minutes, seconds and milliseconds.

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.Month;
import java.time.temporal.ChronoUnit;

public class LocalDateTimeDiff {
    public static void main(String[] args) {
        LocalDateTime from = LocalDateTime.of(2021, Month.JANUARY, 10, 10, 0, 30);
        LocalDateTime to = LocalDateTime.now();

        LocalDateTime fromTemp = LocalDateTime.from(from);
        long years = fromTemp.until(to, ChronoUnit.YEARS);
        fromTemp = fromTemp.plusYears(years);

        long months = fromTemp.until(to, ChronoUnit.MONTHS);
        fromTemp = fromTemp.plusMonths(months);

        long days = fromTemp.until(to, ChronoUnit.DAYS);
        fromTemp = fromTemp.plusDays(days);

        long hours = fromTemp.until(to, ChronoUnit.HOURS);
        fromTemp = fromTemp.plusHours(hours);

        long minutes = fromTemp.until(to, ChronoUnit.MINUTES);
        fromTemp = fromTemp.plusMinutes(minutes);

        long seconds = fromTemp.until(to, ChronoUnit.SECONDS);
        fromTemp = fromTemp.plusSeconds(seconds);

        long millis = fromTemp.until(to, ChronoUnit.MILLIS);

        System.out.println("From = " + from);
        System.out.println("To   = " + to);
        System.out.printf("The difference is %s years, %s months, %s days, " +
                        "%s hours, %s minutes, %s seconds, %s millis",
                years, months, days, hours, minutes, seconds, millis);
    }
}

The result of the code snippet above when executed is:

From = 2021-01-10T10:00:30
To   = 2021-11-17T15:07:37.913247900
The difference is 0 years, 10 months, 7 days, 5 hours, 7 minutes, 7 seconds, 913 millis