Introduction to the Java Date/Time API

Java supports creating and modifying the date and time using primarily two packages java.time and java.util. The package java.time was part of Java 8 release (JSR-310) that introduced the new immutable classes solving the shortcomings of the legacy java.util.Date and java.util.Calendar classes.

1. Legacy Date Time API (Prior to Java 8)

1.1. Core Classes

The primary legacy classes to manipulate date and time were :

  • java.util.Date: represents a specific instant in time, with millisecond precision.
  • java.util.Calendar: an abstract class that provides methods for converting between instances and manipulating the calendar fields in difefrent ways.
  • java.text.SimpleDateFormat: a concrete class for formatting and parsing dates in a locale-sensitive manner and any predefined as well as any user-defined pattern.
  • java.util.TimeZone: represents a time zone offset, and also figures out daylight savings.
  • System.currentTimeMillis(): represents the current date and time as milliseconds since January 1st 1970.

1.2. Challanges

Though these APIs served the simple use cases very much, still Java community continuously complained about the problems in effectively using these classes. For this reason, many other 3rd party libraries (e.g. Joda-Time or classes in Apache Commons) were more popular.

A few of the challenges were:

  • A Date class shall represent a date, but it represents an instance which has hour, minutes and seconds as well.
  • But Date doesn’t have any associated time zone. It picks up the default timezone automatically. You cannot represent a date some other timezone.
  • Classes are mutable. So that leaves additional burden on developers to clone the date before passing a function, which can mutate it.
  • Date formatting classes are also not thread-safe. A formatter instance cannot be used without additional synchronization, else code may break.
  • For some reason, there is another class java.sql.Date which has timzone information.
  • Creating a date with some other timezone is very tricky and often result in incorrect result.
  • Its classes use a zero-index for months, which is a cause of many bugs in applications over the years.

2. New Date Time API (Java 8 Onwards)

The new date api tries to fix the above problems with legacy classes. It contains mainly the following classes:

  • java.time.LocalDate : represents a year-month-day in the ISO calendar and is useful for representing a date without a time. It can be used to represent a date only information such as a birth date or wedding date.
  • java.time.LocalTime : deals in time only. It is useful for representing human-based time of day, such as movie times, or the opening and closing times of the local library.
  • java.time.LocalDateTime : handles both date and time, without a time zone. It is a combination of LocalDate with LocalTime.
  • java.time.ZonedDateTime : combines the LocalDateTime class with the zone information given in ZoneId class. It represent a complete date time stamp along with timezone information.
  • java.time.OffsetTime : handles time with a corresponding time zone offset from Greenwich/UTC, without a time zone ID.
  • java.time.OffsetDateTime : handles a date and time with a corresponding time zone offset from Greenwich/UTC, without a time zone ID.
  • java.time.Clock : provides access to the current instant, date and time in any given time-zone. Although the use of the Clock class is optional, this feature allows us to test your code for other time zones, or by using a fixed clock, where time does not change.
  • java.time.Instant : represents the start of a nanosecond on the timeline (since EPOCH) and useful for generating a timestamp to represent machine time. An instant that occurs before the epoch has a negative value, and an instant that occurs after the epoch has a positive value.
  • java.time.Duration : Differnce between two instants and measured in seconds or nanoseconds and does not use date-based constructs such as years, months, and days, though the class provides methods that convert to days, hours, and minutes.
  • java.time.Period : To define the difference between dates in date-based values (years, months, days).
  • java.time.ZoneId : specifies a time zone identifier and provides rules for converting between an Instant and a LocalDateTime.
  • java.time.ZoneOffset : specifies a time zone offset from Greenwich/UTC time.
  • java.time.format.DateTimeFormatter : provides numerous predefined formatters, or we can define our own. It provides parse() or format() method to parsing and formatting the date time values.
  • TemporalAdjusters: provide many useful inbuilt adjusters for handling recurring events.
  • TemporalQuery: be used as the assignment target for a lambda expression or method reference.
  • DayOfWeek: an enum representing the seven days of the week – Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.

3. Performing Common Tasks

These examples use new classes introduced in Java 8 date time API.

3.1. Get Current Date and Time

All date-time classes have a factory method now() which is the preferred way to get the current date and time in Java 8.

LocalTime currentTime = LocalTime.now();				//13:33:43.557

LocalDate currentDate = LocalDate.now();				//2020-05-03

LocalDateTime currentDateTime = LocalDateTime.now();	//2020-05-03T13:33:43.557

3.2. Parse Date and Time

Date parsing is done with the help of DateTimeFormatter class and parse() methods in date-time classes.

String dateString = "2020-04-08 12:30";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime parsedDateTime = LocalDateTime.parse(dateString, formatter);

System.out.println(parsedDateTime);		//2020-04-08T12:30

3.3. Format Date and Time

Date formatting is done with the help of DateTimeFormatter class and format() methods in date-time classes.

//Format a date
LocalDateTime myDateObj = LocalDateTime.now();

DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");

String formattedDate = myDateObj.format(myFormatObj);
System.out.println(formattedDate);	//	03-05-2020 13:46

3.4. Measure Elapsed Time

To get the elapsed execution time in different time units, use methods such as toDays()toHours()toMillis()toMinutes()toNanos() and getSeconds() from the java.time.Instant and java.time.Duration classes.

Instant start = Instant.now();

//Measure execution time for this method
methodToMeasureExecutionTime();

Instant finish = Instant.now();

long timeElapsed = Duration.between(start, finish).toMillis();  //in millis

3.5. Calculate Days between Two Dates

To calculate number of days between two dates in Java 8 using  ChronoUnit.DAYS.between()  and  LocalDate.until()  methods.

LocalDate date1 = LocalDate.now();
LocalDate date2 = date1.plusDays(99);
 
long diffInDays = ChronoUnit.DAYS.between(date1, date2);

4. Conclusion

The purpose of this tutorial was to introduce you to the legacy Date/Time classes and the challenges faced by the programmers while working with these APIs. We also saw how the new APIs solve the existing challenges using the specific classes for representing the date and time information.

Also, we had a quick look at how to work with the new APIs.

Happy Learning !!

Sourcecode on Github

Leave a Reply

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial