How to Convert Between Date and LocalDateTime

In Java, you can convert between java.util.Date and java.time.LocalDateTime using the java.time API introduced in Java 8. Here’s how you can perform the conversions:


1. Converting Date to LocalDateTime

You need to use java.time.Instant and java.time.ZoneId to make this conversion. Here’s the process:

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateToLocalDateTimeExample {
    public static void main(String[] args) {
        // Create a Date object
        Date date = new Date();

        // Convert Date to LocalDateTime
        LocalDateTime localDateTime = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();

        System.out.println("Date: " + date);
        System.out.println("LocalDateTime: " + localDateTime);
    }
}

2. Converting LocalDateTime to Date

To convert back from LocalDateTime to Date, again you will make use of Instant and ZoneId.

package org.kodejava.datetime;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class LocalDateTimeToDateExample {
    public static void main(String[] args) {
        // Create a LocalDateTime object
        LocalDateTime localDateTime = LocalDateTime.now();

        // Convert LocalDateTime to Date
        Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

        System.out.println("LocalDateTime: " + localDateTime);
        System.out.println("Date: " + date);
    }
}

Explanation:

  1. Date to LocalDateTime:
    • Date.toInstant() converts the Date object into an Instant (a specific point in time).
    • .atZone(ZoneId.systemDefault()) adjusts the instant to your system’s default time zone.
    • .toLocalDateTime() converts the zoned date-time to a LocalDateTime.
  2. LocalDateTime to Date:
    • .atZone(ZoneId.systemDefault()) converts a LocalDateTime into a ZonedDateTime.
    • ZonedDateTime.toInstant() gets an Instant for the given date and time in the local zone.
    • Date.from(Instant) creates a Date object from the Instant.

By using these conversions, you can easily switch between the old java.util.Date and the modern java.time.LocalDateTime API.

How do I determine if a date falls between two dates?

Java provides different ways to determine if a certain date falls within a specified range. In this article, we’ll look at examples using the old java.util.Date and java.util.Calendar classes, as well as the newer Java Date Time API.

Using java.util.Date and java.util.Calendar

Before Java 8, you’d have to use Date or Calendar to work with dates:

package org.kodejava.datetime;

import java.util.Calendar;

public class CheckDateRange {
    public static void main(String[] args) {
        Calendar start = Calendar.getInstance();
        start.set(2024, Calendar.JANUARY, 1);
        Calendar end = Calendar.getInstance();
        end.set(2024, Calendar.DECEMBER, 31);
        Calendar target = Calendar.getInstance();
        target.set(2024, Calendar.JUNE, 15);

        if ((target.after(start) || target.equals(start)) &&
            (target.before(end) || target.equals(end))) {
            System.out.println("The date is within the range.");
        } else {
            System.out.println("The date is not within the range.");
        }
    }
}

The disadvantage with this approach is the excessive verbosity and error-prone copy-pasting necessary for setting up the Calendar instances.

The Java 8 Way – Using java.time.LocalDate

Java 8 introduced the new Java Date Time API, which replaced the inconsistent Date and Calendar classes with the more intuitive LocalDate, LocalTime, LocalDateTime, and ZonedDateTime. Here’s the same task performed using LocalDate:

package org.kodejava.datetime;

import java.time.LocalDate;

public class AnotherCheckDateRange {
    public static void main(String[] args) {
        LocalDate startDate = LocalDate.of(2024, 1, 1);
        LocalDate endDate = LocalDate.of(2024, 12, 31);
        LocalDate targetDate = LocalDate.of(2024, 6, 15);

        if ((!targetDate.isBefore(startDate)) && (!targetDate.isAfter(endDate))) {
            System.out.println("The date is within the range.");
        } else {
            System.out.println("The date is not within the range.");
        }
    }
}

In this code, startDate and endDate define the range of dates. The targetDate is the date you want to check.

The isBefore() method returns true if the targetDate is before the startDate, and the isAfter() method returns true if the targetDate is after the endDate. So, if targetDate is not before the startDate and not after the endDate, it means that the targetDate is between startDate and endDate (inclusive). If the targetDate is exactly the same as startDate or endDate, this condition will also return true.

This simplified API requires significantly less code and eliminates a number of potential bugs and inconsistencies.

Conclusion

The older java.util.Date and java.util.Calendar facilities for working with dates are widely considered difficult to use and error-prone. While they work for simple tasks, the newer Java Date Time API is recommended for all new applications due to its simplicity, consistency, and flexibility. It aligns with ISO standards and covers a comprehensive range of use-cases needed for date-time calculations. Migrating from older APIs to Java 8 Date Time API is likely advantageous for most projects.

How do I iterate through date range in Java?

The following code snippet shows you how to iterate through a range of dates in Java. We use the Java Date Time API. We do increment and decrement iteration using a simple for loop.

Here are the steps:

  • We declare the start and end date of the loop, the dates are instance of java.time.LocalDate.
  • Create a for loop.
  • In the for loop we set the initialization variable the start date.
  • The loop executed if the date is less than end date, using the isBefore() method, otherwise it will be terminated.
  • The date will be incremented by 1 on each loop.
package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

public class DateIteration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023, 10, 1);
        LocalDate end = LocalDate.of(2023, 10, 8);

        System.out.println("Start = " + start);
        System.out.println("End   = " + end);
        System.out.println("--------------------");

        for (LocalDate date = start; date.isBefore(end); date = date.plusDays(1)) {
            System.out.printf("Date %tD is %s%n", date, date.getDayOfWeek());
        }

        System.out.println("--------------------");

        for (LocalDate date = end; date.isAfter(start); date = date.minusDays(1)) {
            System.out.printf("Date %tD is %s%n", date, date.getDayOfWeek()
                    .getDisplayName(TextStyle.SHORT, Locale.getDefault()));
        }
    }
}

Running the code snippet gives you the following output:

Start = 2023-10-01
End   = 2023-10-08
--------------------
Date 10/01/23 is SUNDAY
Date 10/02/23 is MONDAY
Date 10/03/23 is TUESDAY
Date 10/04/23 is WEDNESDAY
Date 10/05/23 is THURSDAY
Date 10/06/23 is FRIDAY
Date 10/07/23 is SATURDAY
--------------------
Date 10/08/23 is Sun
Date 10/07/23 is Sat
Date 10/06/23 is Fri
Date 10/05/23 is Thu
Date 10/04/23 is Wed
Date 10/03/23 is Tue
Date 10/02/23 is Mon

Next, we are going to use while loop.

  • Define the start and end date to loop
  • We increment the start date by 1 day.
  • Execute the loop if the start date is before end date.
package org.kodejava.datetime;

import java.time.LocalDate;

public class WhileDateIteration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023, 10, 1).minusDays(1);
        LocalDate end = LocalDate.of(2023, 10, 8);

        while ((start = start.plusDays(1)).isBefore(end)) {
            System.out.printf("Date %tD is %s%n", start, start.getDayOfWeek());
        }
    }
}

The result of the code snippet above is:

Date 10/01/23 is SUNDAY
Date 10/02/23 is MONDAY
Date 10/03/23 is TUESDAY
Date 10/04/23 is WEDNESDAY
Date 10/05/23 is THURSDAY
Date 10/06/23 is FRIDAY
Date 10/07/23 is SATURDAY

To use the Java stream, we can do it like the following code snippet:

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.stream.Stream;

public class StreamDateIteration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023, 10, 1);
        LocalDate end = LocalDate.of(2023, 10, 8);

        Stream.iterate(start, date -> date.plusDays(1))
                .limit(ChronoUnit.DAYS.between(start, end))
                .forEach(date -> {
                    System.out.printf("Date %tD is %s%n", date, date.getDayOfWeek());
                });
    }
}

The result of the code snippet above is:

Date 10/01/23 is SUNDAY
Date 10/02/23 is MONDAY
Date 10/03/23 is TUESDAY
Date 10/04/23 is WEDNESDAY
Date 10/05/23 is THURSDAY
Date 10/06/23 is FRIDAY
Date 10/07/23 is SATURDAY

From Java 9 we can use LocalDate.datesUntil() method. It will iterate from the date to the specified end date by increment step of 1 day or the specified increment of Period.

package org.kodejava.datetime;

import java.time.LocalDate;
import java.time.Period;

public class DatesUntilDateIteration {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023, 10, 1);
        LocalDate end = LocalDate.of(2023, 10, 8);

        start.datesUntil(end).forEach(date -> {
            System.out.printf("Date %tD is %s%n", date, date.getDayOfWeek());
        });

        start.datesUntil(end, Period.ofDays(2)).forEach(System.out::println);
    }
}

Running the code snippet produces the following result:

Date 10/01/23 is SUNDAY
Date 10/02/23 is MONDAY
Date 10/03/23 is TUESDAY
Date 10/04/23 is WEDNESDAY
Date 10/05/23 is THURSDAY
Date 10/06/23 is FRIDAY
Date 10/07/23 is SATURDAY
2023-10-01
2023-10-03
2023-10-05
2023-10-07

How do I set the time of java.util.Date instance to 00:00:00?

The following code snippet shows you how to remove time information from the java.util.Date object. The static method removeTime() in the code snippet below will take a Date object as parameter and will return a new Date object where the hour, minute, second and millisecond information hasbeen reset to zero. To do this, we use the java.util.Calendar. To remove time information, we set the calendar fields of Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND and Calendar.MILLISECOND to zero.

package org.kodejava.util;

import java.util.Calendar;
import java.util.Date;

public class DateRemoveTime {
    public static void main(String[] args) {
        System.out.println("Now = " + removeTime(new Date()));
    }

    private static Date removeTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
}

The result of the code snippet above is:

Now = Sat Nov 20 00:00:00 CST 2021

In the above code:

  1. An instance of Calendar is created using Calendar.getInstance().
  2. We set the Calendar time using setTime() method and pass the date object.
  3. The time fields (HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND) are set to zero. Calendar.HOUR_OF_DAY is used for 24-hour clock.
  4. The resulting Calendar instances time value is printed which should now represent the start of the day.

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