JB Header
Java 8 - Working with LocalDate, LocalTime, LocalDateTime - tutorial with examples
Background & Introduction Until Java 7 java.util.Date was all that the JDK provided for handling dates, time, and dates with time. Java 8’s new Date-Time APIRead Overview of what has changed in Java 8's new Date-Time API has acknowledged the difference in these three types of date and time usages and accordingly defined different classes for each of them in the new java.time package. LocalDate, LocalTime and LocalDateTime are thus separate classes, although they are related and interchangeable, thus facilitating date and time handling for a myriad set of scenarios.

Java 8 designers have defined similar method naming and usage patterns for LocalDate, LocalTime and LocalDateTime classes and this would allow us to look at these classes together. The sections in this tutorial are also divided as per the method names, i.e. each section covers a method and its usage for all three classes.

Note - I will refer the three classes, LocalDate, LocalTime and LocalDateTime, together as LocalXXX going forward. What this tutorial covers
  • To begin with, we will first see a quick introduction and understand the purpose of LocalXXX classes.
  • Next we will understand the inherent immutability of the date-time classes.
  • We will then look at the static methods used to create instances of these classes viz. now() and of() methods.
  • Next we will go through the methods meant for modifying individual date-time attributes stored in LocalXXX objects, i.e. the methods with ‘plus’/‘minus’ and ‘with’ prefixes.
  • Lastly, we will take a look at the methods provided for 'getting' specific date-time values from the LocalXXX instances.
Purpose of LocalXXX Date-Time classes java.time.LocalDate: A LocalDate instance holds a date without a time zone, in ISO-86011 calendar system. LocalDate has the default format YYYY-MM-DD as in ‘2016-12-12’.
java.time.LocalTime: A LocalTime holds time in the ISO-8601 calendar system, without any date or time zone information associated with it. The format is typically - ‘HH:mm:ss’ as in ‘12:10:35’. LocalTime can be upto nanosecond precision(after the last second) with the format ‘HH:mm:ss.nnnnnnnnn’ as in ‘12:10:35.123456789’.
java.time.LocalDateTime: Represents a Date and Time without a time zone in the ISO-8601 format. Its typical format is ‘YYYY-MM-DDTHH:mm:ss’. (Notice the 'T' separating days from hours) as in ‘2016-12-12T12:10:35’. LocalDateTime can also have a nanosecond-of-the-second component like in LocalTime. Immutability of LocalXXX Classes The instances of all three classes - LocalDate, LocalTime and LocalDateTime are immutable. I.e. the LocalXXX objects with a specific date and/or time information, once created, cannot be modified.

You might come across many methods, including the ones explained further in this tutorial, which modify LocalXXX objects and returned objects with modified values. It is important to note that what you are getting back from these modification methods are in fact new immutable objects and not the modified versions of previous objects. So, in order to not allow errors to creep in your logic, always assign the returned objects from methods such as plus()/minus()/with() etc to a new LocalXXX object of the same type, and then use this new object further in your code.

Having understood what values LocalDate, LocalTime or LocalDateTime hold, let us now take a look at the methods which the new Date-Time API provides to us in order to instantiate, modify, and fetch values from the LocalXXX objects. Creation of LocalXXX instances The 2 most important ways in which you will be instantiating LocalXXX objects are via the static methods now() and of() -
  1. Using static method LocalXXX.now() method: All three date-time classes provide the static method now() which fetches the date(for LocalDate), time(for LocalTime) and date-time(for LocalDateTime) from the system clock of the machine on which the JVM is running. Given next are the three methods in action, followed by output showing the values returned by these methods.
    Java 8 code showing LocalXXX.now() usage
    LocalDate localDate = LocalDate.now();
    System.out.println("localDate: "+localDate);
    
    LocalTime localTime =LocalTime.now();
    System.out.println("localTime: "+localTime);
    
    LocalDateTime localDateTime =LocalDateTime.now();
    System.out.println("localDateTime: "+localDateTime);
     OUTPUT of the above code
    localDate:  2016-12-16
    localTime:  12:15:26.343
    localDateTime:  2016-12-16T12:15:26.344
  2. Using static method LocalXXX.of() method: LocalXXX.of() method takes as input the individual values constituting date-time as int parameters. These are values corresponding to date, month, year, hours, minutes, seconds and seconds in int format. Usage of of() method is as follows -
    Java 8 code showing LocalXXX.of() usage
    LocalDate localDate = LocalDate.of(2016,12,01);
    System.out.println("localDate: "+localDate);
    
    LocalTime localTime =LocalTime.of(23,12,56,234);
    System.out.println("localTime: "+localTime);
    
    LocalDateTime localDateTime =LocalDateTime.of(2016,12,01,23,12,56,234);
    System.out.println("localDateTime: "+localDateTime);
    
    LocalDate localDateNov = LocalDate.of(2016, Month.NOVEMBER,01);
    System.out.println("localDateNov: "+localDateNov);
     OUTPUT of the above code
    localDate:  2016-12-01
    localTime:  23:12:56.000000234
    localDateTime:  2016-12-01T23:12:56.000000234
    localDateNov:  2016-11-01
    • First an instance of LocalDate, named localDate, is created for year=2016, month=12, and date=01.
    • Next an instance of LocalTime, named localTime, is created for hour=23, minute=12, second=56, and nanosecond=234.
    • Next a LocalDateTime instance is created wherein the same int values used for localDate and localTime are passed as input to the of() method.
    • Lastly, an overridden usage of LocalDate.of() method is shown where for the month an enum value - Month.November is passed to create localDateNov instance.
(Note - There is another method for creating the LocalXXX instances which is parse(). I will cover this method in a separate detailed tutorial on Java8 Date-Time parsing and formatting.)
Modifying LocalXXX instances Modification of LocalDate, LocalTime and LocalDateTime objects can be done via two varieties of methods - the methods with prefix as 'plus'/'minus' and those with prefix 'with'.
  1. LocalXXX.plus()/minus() methods: The plus/minus methods work by adding or subtracting the required number of days, months, years, hours, minutes, seconds and nanoseconds to LocalXXX objects. Each of the LocalXXX classes provide methods for plus/minus for each field of date and time they store. So, LocalDate has plusDays() and minusDays() methods, while LocalTime has a plusMinutes() and minusMinutes() methods, and so on. Let us see a few of the variants of these methods in action. For further examples on these methods you can refer the tutorial on Java 8 date-time calculationsRead tutorial on Java 8 Date-Time calculations.
    Java 8 code showing LocalXXX.plus()\minus() methods usage
    System.out.println("Today: "+LocalDate.now());
    LocalDate todayPlus10Days=LocalDate.now().plusDays(10);
    System.out.println("localDatePlus10: "+todayPlus10Days);
    
    System.out.println("Time Now: "+LocalTime.now());
    LocalTime nowMinus20Minutes=LocalTime.now().minusMinutes(20);
    System.out.println("nowMinus20Minutes: "+nowMinus20Minutes);
    
    System.out.println("Date-Time Now: "+LocalDateTime.now());
    LocalDateTime nowPlus2Years =LocalDateTime.now().plusYears(2);
    System.out.println("todayPlus2Years: "+nowPlus2Years);
     OUTPUT of the above code
    Today:  2016-12-16
    localDatePlus10:  2016-12-26
    
    Time Now:  20:36:26
    nowMinus20Minutes:  20:16:26
    
    Date-Time Now:  2016-12-16T20:36:26
    todayPlus2Years:  2018-12-16T20:36:26
    • First example for LocalDate - creates an instance of LocalDate using LocalDate.now(), and then adds 10 days to it using plusDays(10).
    • Second example for LocalTime - creates an instance of LocalTime using LocalTime.now(), and then subtracts 20 minutes from it using minusMinutes(20).
    • Third example for LocalDateTime - creates a LocalDateTime instance using the now() method, and then adds 2 years to it using plusYears(2).
    • Note - there couple of variants of plus() and minus() operations which are defined in Temporal3- the parent interface of LocalXXX classes. I will be covering the Temporal/TemporalUnit/TemporalAmount handling in a separate tutorial on temporals.
  2. LocalXXX.with() methods:The with methods work by setting the required number of days, months, years, hours, minutes, seconds and nanoseconds in the LocalXXX objects. Each of the LocalXXX classes provide specific with() methods for setting each each field of date and time they store. So, LocalDate has a withDaysOfMonth() method, while LocalTime has a withMinute() method, and so on. Let us see a few of the variants of these methods in action -
    Java 8 code showing LocalXXX.with() methods usage
    System.out.println("Today: "+LocalDate.now());
    LocalDate dayOfMonth20=LocalDate.now().withDayOfMonth(20);
    System.out.println("Day of month set as 20: "+dayOfMonth20);
    
    System.out.println("Time Now: "+LocalTime.now());
    LocalTime minute0=LocalTime.now().withMinute(0);
    System.out.println("Minutes set to 0: "+minute0);
    
    System.out.println("Date-Time Now: "+LocalDateTime.now());
    LocalDateTime month10 =LocalDateTime.now().withMonth(10);
    System.out.println("Month set to 10: "+month10);
     OUTPUT of the above code
    Today:  2016-12-19
    Day of month set as 20:  2016-12-20
    
    Time Now:  15:13:27.175
    Minutes set to 0:  15:00:27.175
    
    Date-Time Now:  2016-12-19T15:13:27.176
    Month set to 10:  2016-10-19T15:13:27.176
    • First example for LocalDate - creates an instance of LocalDate using LocalDate.now(), and then sets the day value to 20.
    • Second example for LocalTime - creates an instance of LocalTime using LocalTime.now(), and then sets the minutes value to 00.
    • Third example for LocalDateTime - creates a LocalDateTime instance using the now() method, and then sets the month value to 10.
    • Note - there couple of variants of with() operations which are defined in Temporal which use TemporalAdjuster and TemporalField values. I will be covering these in separate tutorials on TemporalAdjuster and Temporal respectively.
Fetching individual fields of LocalXXX All three LocalXXX classes define methods to fetch individual values of their fields. The naming of these methods matches the naming for with() methods in the classes. So, LocalDate has getDayofMonth(), getMonth(), getDays() methods, while LocalTime has getHour(), getMinute(), getSecond(), getNano() methods. Similarly there are get() methods for LocalDateTime. Let us see a few of these methods used in code to better understand their usage -
Java 8 code showing fetching individual fields using get() methods
System.out.println("Today: "+LocalDate.now());
int dayOfMonth=LocalDate.now().getDayOfMonth();
System.out.println("Day of month is: "+dayOfMonth);

System.out.println("Time Now: "+LocalTime.now());
int minute=LocalTime.now().getMinute();
System.out.println("Minutes value is: "+minute);

System.out.println("Date-Time Now: "+LocalDateTime.now());
Month month = LocalDateTime.now().getMonth();
System.out.println("Month value is: "+month.getValue());
 OUTPUT of the above code
Today:  2016-12-19
Day of month is:  19

Time Now:  15:42:08.775
Minutes value is:  42

Date-Time Now:  2016-12-19T15:42:08.775
Month value is:  12
  • First example for LocalDate - creates an instance of LocalDate using LocalDate.now(), and then fetches the value of day using getDayOfMonth() as 19.
  • Second example for LocalTime - creates an instance of LocalTime using LocalTime.now(), and then fetches the value of minute using getMinute() as 42.
  • Third example for LocalDateTime - creates a LocalDateTime instance using the now() method, and then fetches the value of month by using getMonth() to get an instance of java.time.Month and then using Month.getValue() to get the value as 12.
  • Note - there are couple of variants of get() operations which are defined in TemporalAccessor4- which all LocalXXX classes implement - which use TemporalField values. I will be covering these in separate tutorials on Temporals.
Summary In the above tutorial we understood how to work with LocalDate, LocalTime and LocalDateTime classes. We understood the purpose of each of the date-time classes, learnt the implications of their immutable instances, saw how to create, modify and fetch the values of each of the classes using their similarly-named methods.

1. ISO-8601 calendar system refers to the 24-hour date and time format which is most commonly used in the day-to-day parlance. The formal definition of this format, for easing communications across countries, is captured under ISO-8601.