One of the latest features to be introduced in Java 8 is the ‘DateTime API’. Enabling users to easily perform date and time manipulation, this new feature is one of Java 8’s most exciting to date (it’s certainly loved by the hackajob team!). Within this article, we’ll be explaining why this API was added and introducing you to the following classes:
- LocalDate
- LocalTime
- LocalTimeDate
Why was the DateTime API Introduced?
Prior to Java 8, the java.util.Date and java.util.Calendar classes were used for handling dates, however, these classes have several disadvantages:
- They don’t offer many features and aren’t very user-friendly. As an example, if you wanted to find the number of days between two days, you’d need to write some complex logic.
- The ‘Date’ and ‘Calendar’ classes don’t support time zones easily. Because of this, you’d need to write a lot of code in order to handle different time zones.
- Whilst the ‘Date’ and ‘Calendar’ classes do have a time component, there were no separate classes corresponding to time before Java 8.
- Not thread safe, the ‘Date’ and ‘Calendar’ classes require external synchronisation code in order to be written.
To overcome the issues outlined above, Java 8 introduced the DateTime API, with all the classes in the API belonging to the java.time package.
LocalDate, LocalTime and LocalDateTime
The most important classes in the DateTime API (and the ones you’re are most likely to use) are the ‘LocalDate’, ‘LocalTime’ and ‘LocalDateTime’ classes. Let’s explore them in more detail:
LocalDate
The LocalDate class represents a date and has the year, month and day components. As an example, you can use it to represent a date like 14 September 2010. Note that it doesn’t have a time component.
Creating a LocalDate
There are several static methods on the LocalDate class that can be used to create a LocalDate, like so:
LocalDate date1 = LocalDate.now();
System.out.println("Today's date : "+date1);
LocalDate date2 = LocalDate.parse("2019-07-15");
System.out.println("Date2 : "+date2);
LocalDate date3 = LocalDate.of(2017,05,17);
System.out.println("Date3 : "+date3);
The LocalDate.now returns the current date, and the LocalDate.parse parses a date in a String format and creates a LocalDate object out of it. Requiring the String date to be in a yyyy-MM-dd format, if you specify the date in a different format, an error will occur. Not to worry, you can always use the overloaded version of the parse method that accepts a DateTimeFormatter if required. Finally, the LocalDate.of method creates a LocalDate object using the specified month, date and year.
When this code is executed, the following output will be printed to the console:
Today's date : 2019-08-20
Date2 : 2019-07-15
Date3 : 2017-05-17
In addition to these methods, the LocalDate class has many other options that can be used to create a LocalDate.
Date Arithmetic
The LocalDate allows you to easily perform date arithmetic. For example, you can add or subtract days, weeks, months or years from a date. The following code demonstrates this:
LocalDate date1 = LocalDate.parse("2019-07-15");
LocalDate date2 = date1.plusDays(5);//add 5 days
System.out.println(date1+" +5 day: "+date2);
date2 = date1.minusMonths(6);//subtract 6 months
System.out.println(date1+" -6 months: "+date2);
date2 = date1.withYear(2014);// set year to 2014;
System.out.println(date1+" with Year 2014 "+date2);
In the code above, you can see that the LocalDate.plusDays method adds the specified number of days to the LocalDate object. From there, the LocalDate.minusMonths subtracts the specified number of months from the LocalDate object, whilst the LocalDate.withYear sets the year field to the specified value.
When the code is executed, the following output will be printed to the console:
2019-07-15 +5 day: 2019-07-20
2019-07-15 -6 months: 2019-01-15
2019-07-15 with Year 2014: 2014-07-15
Note that the above examples are not the only methods that you can use to perform date arithmetic with the LocalDate class.
Extracting Information from LocalDate
The LocalDate class allows you to easily extract information, such as the year, month, date, day of the year and more, from the LocalDate object. The following code shows how this works:
LocalDate date = LocalDate.of(2017, Month.JULY, 15);
int day = date.getDayOfYear();
System.out.println("DayOfYear="+day);
int dayOfmonth = date.getDayOfMonth();
System.out.println("DayOfmonth="+dayOfmonth);
Month month = date.getMonth();
System.out.println("Month="+month);
DayOfWeek dayOfWeek = date.getDayOfWeek();
System.out.println("DayOfWeek="+dayOfWeek);
The LocalDate.getDayOfYear returns the day of the year that the LocalDate corresponds too. From there, the LocalDate.getDayOfMonth returns the day of month component from the LocalDate. The LocalDate.getMonth then returns the month component from the LocalDate and finally, the LocalDate.getDayOfWeek returns the day of the week component from the LocalDate.
When this code is executed, the following output will be printed to the console:
DayOfYear=196
DayOfmonth=15
Month=JULY
DayOfWeek=SATURDAY
In addition to the methods outlined above, the LocalDate class offers multiple options that allow you extract information from the LocalDate object.
Date Comparison
The LocalDate class allows you to easily compare LocalDate objects to check if a date is before or after another date. The following code demonstrates how this works:
LocalDate date1 = LocalDate.parse("2017-05-17");
LocalDate date2 = LocalDate.parse("2014-09-14");
boolean isAfter= date1.isAfter(date2);
System.out.println(date1+" Is after "+date2+" "+isAfter);
LocalDate date3 = LocalDate.of(2017, 05, 17);
boolean isEqual = date1.isEqual(date3);
System.out.println(date1+" Is Equal "+date3+" "+isEqual);
boolean isLeapYear = date1.isLeapYear();
System.out.println(date1+" Is LeapYear "+isLeapYear);
Note that the LocalDate.isAfter method returns true if the LocalDate object on which the method is invoked is after the LocalDate object passed in. As well as this, the LocalDate.isEqual method returns true if both LocalDate objects refer to the same date and the LocalDate.isLeapYear returns true if the LocalDate object is a Leap Year.
When you execute the above code, the following is printed to the console:
2017-05-17 Is after 2014-09-14 true
2017-05-17 Is Equal 2017-05-17 true
2017-05-17 Is LeapYear false
LocalTime
Introduction
The LocalTime class represents a time of your choosing. It has the hour, minute, second and nanoseconds components. For example, you can use it to represent a time like 7:30. It doesn’t have year, month and day components.
Just like LocalDate, LocalTime has several static methods that can be used to create a LocalTime instance. The following code demonstrates some of these methods:
LocalTime time1 = LocalTime.now();
System.out.println("Current time : "+time1);
LocalTime time2 = LocalTime.parse("12:30");
System.out.println("time2 : "+time2);
LocalTime time3 =LocalTime.ofSecondOfDay(200);
System.out.println("time3 : "+time3);
From the code above, we can see that the LocalTime.now returns the current time, whilst the LocalTime.parse parses the specified date and time and creates a LocalTime object out of this. Just like LocalDate, if your string time is in a different format, you can use the overloaded version of the parse method that accepts a DateTimeFormatter. As well as this, the LocalTime.ofSecondDay method creates a LocalTime object using the ‘second of day’ value.
When this code is executed, it will print the following:
Current time : 12:46:08.675
time2 : 12:30
time3 : 00:03:20
LocalTime Operations
Like LocalDate, there are several methods on the LocalTime class that can be used to perform time manipulation or extract time information. The following code demonstrates just some of these operations:
LocalTime time = LocalTime.parse("12:30").plusMinutes(10);
System.out.println("12:30 Plus 10 minutes : "+time);
int hour = time.getHour();
System.out.println(time+" Hour : "+hour);
long second = LocalTime.parse("00:30").toSecondOfDay();
System.out.println("00:30 in seconds : "+second);
The LocalTime.plusMinutes method adds the specified number of minutes to the LocalTime object. From there, the LocalTime.getHour returns the hour component in the LocalTime object and the LocalTime.toSecondOfDay method will return the time in seconds.
When this code is executed, the following output will be printed to the console:
12:30 Plus 10 minutes : 12:40
12:40 Hour : 12
00:30 in seconds : 1800
In addition to these methods, the LocalTime class has many more methods that allow you to perform multiple operations.
LocalDateTime
Introduction
The LocalDateTime class is a date and time class that features the following components:
- Day
- Month
- Year
- Hour
- Minute
- Second
- Nanosecond
As an example, you can use it to represent a time like 12th January 1995 7:30 PM.
Just like LocalDate and LocalTime, the LocalDateTime class has several static methods that can be used to create a LocalDateTime instance. You can also create a LocalDateTime instance using a LocalDate and LocalTime instance. The following code demonstrates this:
LocalDateTime dateTime1 = LocalDateTime.now();
System.out.println("Current DateTime : "+dateTime1);
LocalDateTime dateTime2 = LocalDateTime.of(LocalDate.parse("2013-03-24"),LocalTime.parse("06:45"));
System.out.println("DateTime2 : "+dateTime3);
From the code above, we can see that the LocalDateTime.now returns the current time, whilst the LocalTime.of method creates a LocalDateTime object using a LocalDate and LocalTime instance. There are several other versions of the ‘of’ method that can be used to make a LocalDateTime, using ‘year’, ‘month’ and ‘day of year’ as examples.
When this code is executed, it will print the following output:
Current DateTime : 2019-08-21T12:49:04.621
DateTime2 : 2013-03-24T06:45
As you can see from the above output, the date and time components are separated by the letter ‘T’.
LocalDateTime Operations
Just like LocalDate and LocalTime, there are several methods that the LocalDateTime class has available for date and time manipulation. In addition, this class also includes methods that can be used to extract a LocalDate or LocalTime. The following code demonstrates just some of these operations:
LocalDateTime dateTime1 = LocalDateTime.of(2018,9,8,5,25);
LocalDateTime dateTime2 = dateTime1.plusWeeks(3);
System.out.println("Date "+dateTime1+" plus 3 weeks : "+dateTime2);
int minute = dateTime1.getMinute();
System.out.println("Minute :"+minute);
LocalDate date = dateTime1.toLocalDate();
System.out.println("Date :"+date);
LocalTime time = dateTime1.toLocalTime();
System.out.println("Time :"+time);
Above, we can see that the LocalDateTime.plusWeeks method adds the specified number of weeks to the LocalDateTime object. From there, the LocalDateTime.getMinute method returns the minute component in the LocalDateTime object. The LocalDateTime.toLocalDate returns the LocalDate component in the LocalDateTime object and finally, the LocalDateTime.toLocalTime method returns the LocalTime component in the LocalDateTime object.
When the code above is executed, it will print the following output:
Date 2018-09-08T05:25 plus 3 weeks : 2018-09-29T05:25
Minute : 25
Date : 2018-09-08
Time : 05:25
Thanks for taking the time to read Part 1 of this article. In Part 2, we’ll be exploring some of the other classes in the DateTime API, including ‘ZonedDateTime’, ‘Period’ and ‘Duration’. In the meantime, make sure to check out our previous Java 8 articles to see what we’ve been working on so far.