Java 8 introduced a new API for Date and Time. In this post, we will cover some of the features of the Java 8 Date Time API.
Java 1.0 introduced support for date and time using java.util.Date class.This API contains a lot of issues including not representing the date as a human-readable date but point in time with milliseconds.We will cover some of the issues or drawbacks of the existing Date API which made way for the Java 8 Date Time API.
Due to all these designs flaws and inconsistencies, most of the enterprise applications were forced to use third party solution like Joda-Time etc. To resolve all these issues, Java 8 introduced a brand new Date and Time API which is integrate many of the Joda-Time API features.
LocalDate, LocalTime, and LocaleDateTime are the most commonly used classes in the new Date API. These classes provide information independent of time zone i.e we do not need to worry about the time zone.
LocalDate represents date without time zone in ISO format. This is one of the most commonly used classes in the new Date API.An instance of this class is immutable and represents date without information of the time and timezone.
LocalDate provides multiple utility methods to create an instance of this class. We can use of static factory method of the LocalDate class to create an instance of this class.
LocalDate date = LocalDate.of(2018, 01,8); //2018-01-08
Above code will represent the LocalDate for 8 January 2018. LocalDate instance provides a number of different methods which can be used for the most common values required while working to Date. We will cover some of the methods in this section.
LocalDate date = LocalDate.of(2018, 01,8); int year = date.getYear(); //2018. boolean isLeap = date.isLeapYear(); //f alse, 2018 is not Leap Year int day = date.getDayOfMonth(); // 8 DayOfWeek dayOfWeek =date.getDayOfWeek(); //MONDAY Month month =date.getMonth(); //JANUARY int monthLength = date.lengthOfMonth(); //31 int daysOfYear = date.getDayOfYear(); // 8
We can use
LocalDate.now() factory method to obtain current date based on the system clock.
LocalDate systemDate = LocalDate.now(); //2018-01-08
LocalDate provides other utility methods to get a different kind of information. We will cover different operations that can be performed on the LocalDate object in other section of this post.
LocalTime represents a time of the day (e.g 20:22: 12) without time zone and date.Like LocalDate, we can get an instance of LocalTime by using the static factory method.
LocalTime time = LocalTime.of(20, 45); //20:45 LocalTime time = LocalTime.of(20, 45, 12); //20:45 : 12
LocalTime class provides numbers of utility method to get information from the LocalTime instance.
LocalTime time = LocalTime.of(20, 45, 34); //20:45:34 int hour = time.getHour(); //20 int minutes = time.getMinute(); //45 int seconds = time.getSecond(); //34
To get time zone independent current LocalTime based on the system clock, we can use LocalTime.now() factory method.
LocalTime systemTime = LocalTime.now(); //20:49:35.509403
We can also create an instance of LocalTime by parsing String using LocalTime.parse() method
LocalTime systemTime = LocalTime.parse("15:45:45"); //15:45:45
LocalDateTime is the combination of LocalDate and LocalTime. LocalDateTime represents date and time without time zone. We can create an instance of the LocalDateTime class by using now method or we can combine date and time instance to create the LocalDateTime object.
LocalDateTime localDateTime = LocalDateTime.of(2018, Month.JANUARY, 8, 21, 26, 12); //2018-01-08T21:26:12 LocalDate date= LocalDate.now(); LocalTime time = LocalTime.now(); LocalDateTime combieDataIssue = LocalDateTime.of(date,time); //2018-01-08T21:30:03.663603 LocalDateTime ldt = date.atTime(time); //2018-01-08T21:41:50.068417 LocalDateTime ldt1 = time.atDate(date); //2018-01-08T21:41:50.068417
Use Duration class to represent time in seconds and nanoseconds and Period for the time in years, months and days.
Duration is the time-based amount of time (e.g 12.4 seconds etc), here are some of the example for Duration
Duration twoMinutes = Duration.ofMinutes(3); Duration duration = Duration.of(3, ChronoUnit.MINUTES); LocalDateTime localDateTime = LocalDateTime.now(); LocalDateTime localDateTime1 =LocalDateTime.of(2018, Month.JUNE, 5, 10, 15, 45); Duration duration1 = Duration.between(localDateTime1, localDateTime);
A date-based amount of time in the ISO calendar system.The period class can be used to modify a value for a given date or to find the difference between dates. Let’s take an example to understand how this can be used.
LocalDate initialDate= LocalDate.of(2017, 10, 11);
Use the period class to get useful information from the 2 date instances.
Period days = Period.ofDays(4); Period weeks = Period.ofWeeks(3); LocalDate initialDate= LocalDate.of(2017, 10, 11); LocalDate finalDate = LocalDate.of(2017, 11, 15); int dayDuration = Period.between(initialDate, finalDate).getDays(); //4 int monthDuration = Period.between(finalDate,initialDate).getMonths(); // -1
Read our article Java 8 Date Time API for more details on Duration and Period classes in the new API.
One of the main features of the Java 8 Date Time API is thread safety and most of the classes we discussed are immutable.In certain cases, we might need we need a new instance of the give LocaleDate instance to work with.
To create a new object for the given LocalDate, we can use one of it’s withAttribute or more generic with a method.
LocalDate currentDate = LocalDate.now(); //current system date LocalDate withYearDate= currentDate.withYear(2017); //Returns a copy of this date with the year altered //2017-01-09 LocalDate daysOfMonth = withYearDate.withDayOfMonth(12); // Returns a copy of this date with the day-of-month altered // 2017-01-12
These methods return a new object without keeping original LocalDate instance unchanged.
New Java 8 Date Time API provides convenient ways to manipulate LocalDate instance. We can perform add, subtract on given Date instance.
//Date Manipulation LocalDate date = LocalDate.of(2017, 8, 23); LocalDate date1 = date.plus(1, ChronoUnit.DAYS); // 2017-08-24 LocalDate date2 = date1.plusWeeks(1); // 2017-08-31 , one week added to date LocalDate addYear = date2.plusYears(2); // 2019-08-31 , added 2 years LocalDate minusYear = date2.minusYears(4); // 2013-08-31 LocalDate fromYear = minusYear.from(ZonedDateTime.now());
Please note that like
withAttribute methods defined in the earlier section, These methods return a new Object with modified attributes.
Before Java 8 parsing and formatting of Date object were not very easy. Java 8 new java.time.format package provides a lot of helpful methods to format or parse date easily.
DateTimeFormatter is one of the most important class under this package. We can use parse() method of the LocalDate instance to format given date instance.
LocalDate date = LocalDate.of(2011, 12, 17); String formattedDate = date.format(DateTimeFormatter.BASIC_ISO_DATE); // 20111217
Use DateTimeFormatter for converting String to the LocalDate instance.
LocalDate stringFormattedDate = LocalDate.parse("20161217", DateTimeFormatter.BASIC_ISO_DATE); // 2016-12-17 LocalDate date1 = LocalDate.parse("2016-08-17", DateTimeFormatter.ISO_LOCAL_DATE); // 2016-08-17
DateTimeFormatter provides a number of formatter to work with, however,
The DateTimeFormatter class provides a static factory method for creating custom formatter.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); LocalDate currentDate = LocalDate.now(); // output : 2018-01-09 String formattedDate1 = currentDate.format(formatter); // output : 09/01/2018 in LocalDate newDate = LocalDate.parse(formattedDate,formatter);
So we did few things in above example of created new LocalDate instance based on new formatter.
If you are looking for Local based formatter, use the overloaded method of DateTimeFormatter by passing Local as an additional parameter.
DateTimeFormatter japaneseFormatter = DateTimeFormatter.ofPattern("M'月' yyyy'年'", Locale.JAPANESE); String newFormatter = currentDate.format(japaneseFormatter); // output : 1月 2018年 LocalDate localDate = LocalDate.parse(formattedDate1,formatter);
This is numbers of benefits of using this new formatter.
The parse() method can throw DateTimeParseException in case it is not able to parse String to a valid LocalDate or LocalTime instance.
New Java Date and Time API provide DateTimeFormatterBuilder class to create complex formatter.
DateTimeFormatter builder = new DateTimeFormatterBuilder() .appendLiteral("Day of Month is :") .appendValue(ChronoField.DAY_OF_MONTH) .appendLiteral(", Month is :") .appendValue(ChronoField.MONTH_OF_YEAR) .appendLiteral(", Year is : ") .appendValue(ChronoField.YEAR) .appendLiteral(", Time is :") .appendValue(ChronoField.HOUR_OF_DAY) .appendLiteral(":") .appendText(ChronoField.MINUTE_OF_HOUR, TextStyle.FULL_STANDALONE) .parseCaseSensitive() .toFormatter(); LocalDateTime localDateTime = LocalDateTime.now(); String date = localDateTime.format(builder);
Current Day is :9, Month is :1, Year is : 2018, Time is :21:16
We covered some of the basic features of Java 8 Date and Time API. There are numbers of features improvement this new API brings in, here are some of the most important features of new API.
In this article, we covered Java 8 Date Time API. We covered different features and improvement introduced by Java Date and Time API. This API is a complete replacement of the old Java API and integrate many of the features of Joda-Time API.