Learn Java

Java Date and Time

Time is a fundamental notion not only in human life but in programming as well. Of course, Java provides some tools for working with temporal entities. We'll start with such units of time measurement as days (or dates).

The LocalDate class represents a single date in the YYYY-MM-dd format, such as 2017-11-25 or 2025-01-23 . It could be used to store any date: from your birthday to the day of the Apocalypse.

The class belongs to the java.time package.

Creating LocalDate and current time

After importing the class, an instance storing the current date can be created as below:

LocalDate now = LocalDate.now();

Of course, it is also possible to create an instance of LocalDate that represents a specific day of a year. It can be obtained by using either of the two special static methods: of and parse.

Here are two examples:

LocalDate date1 = LocalDate.of(2017, 11, 25); // 2017-11-25 (25 November 2017)
LocalDate date2 = LocalDate.parse("2017-11-25"); // 2017-11-25 (25 November 2017)

The numbering system is intuitive: the number of a month is a number from 1 to 12 inclusive, the first day in a month has the number 1.

The other useful way to create an instance of LocalDate is by indicating a year and the sequential number of a day in this year, like this:

LocalDate.ofYearDay(2017, 33); // 2017-02-02 (2 February 2017)

A number of a day in the year is an int number from 1 to 365-366 (depending on whether it is a leap year or not).

LocalDate.ofYearDay(2016, 365); // 2016-12-30 (30 December 2016)
LocalDate.ofYearDay(2017, 365); // 2017-12-31 (31 December 2017)

Be careful though, because an exception may occur when we deal with the 366th day:

LocalDate.ofYearDay(2016, 366); // 2016-12-31 (31 December 2016)
LocalDate.ofYearDay(2017, 366); // here an exception occurs, because the year is not a leap year

LocalDate: year, month, day and length

Let's now consider the following instance of LocalDate:

LocalDate date = LocalDate.of(2017, 11, 25); // 2017-11-25 (25 November 2017)

We can get the year, month, the day of a month, the day of a year:

int year = date.getYear(); // 2017
int month = date.getMonthValue(); // 11
int dayOfMonth = date.getDayOfMonth(); // 25
int dayOfYear = date.getDayOfYear();  // 329

It is also possible to get a length of the year and month:

int lenOfYear = date.lengthOfYear(); // 365
int lenOfMonth = date.lengthOfMonth(); // 30

Arithmetic methods of LocalDate

The class has other methods for adding, subtracting and altering a day, month and year. Let's create another LocalDate instance:

int lenOfYear = date.lengthOfYear(); // 365
int lenOfMonth = date.lengthOfMonth(); // 30

And take a look at how we can apply these methods:

LocalDate tomorrow = date.plusDays(1);    // 2017-01-02 (2 January 2017)
LocalDate yesterday = date.minusDays(1);  // 2016-12-31 (31 December 2016)
LocalDate inTwoYears = date.plusYears(2); // 2019-01-01 (1 January 2019)
LocalDate in2016 = date.withYear(2016);   // 2016-01-01 (1 January 2016)

LocalTime

There's a special class to represent the time of day in Java. The LocalTime class represents daytime in the hours-minutes-seconds format, such as 06:30 or 11:45:30. It doesn't store information about the date or the time zone. Time is stored with nanosecond precision (for example, 13:45:30.123456789). The LocalTime class could be used to store things like the opening and closing hours of a shop or a train schedule.

This class belongs to the java.time package and pretty much resembles the LocalDate class.

Creating LocalTime, current time and constants

First of all, let's see how we create an instance of the LocalTime class. An instance that stores the current time can be created as shown below:

LocalTime now = LocalTime.now();

If we want to pass a specific time to an instance, we should employ either of the two static methods of and parse to create an instance of LocalTime :

LocalTime.of(11, 45);        // 11:45
LocalTime.of(11, 45, 30);    // 11:45:30
LocalTime.parse("11:45:30"); // 11:45:30 (hours, minutes, seconds)

In the first line, second and nanosecond fields will be set to zero.

The hour of a day is an int number from 0 to 23, while minutes and seconds are numbers from 0 to 59. Nanoseconds can be any integer numbers from 0 to 999,999,999. The following code throws an exception:

LocalTime.of(24, 1, 1); // it throws DateTimeException (24 is an invalid value for hours)

It's also possible to create an instance of LocalTime by using static methods ofSecondOfDay and ofNanoOfDay. In this case, we should indicate seconds and nanoseconds of a day respectively:

LocalTime time = LocalTime.ofSecondOfDay(12345); // 03:25:45
LocalTime nanotime = LocalTime.ofNanoOfDay(1234567890); // 00:00:01.234567890

There are some predefined constants in the LocalTime class as well :

LocalTime.MIN; // 00:00
LocalTime.MAX; // 23:59:59.999999999
LocalTime.NOON; // 12:00
LocalTime.MIDNIGHT; // 00:00

Remember that it is a good practice to use constants whenever possible!

LocalTime: hours, minutes and seconds

Now let's discuss a bunch of useful methods of the LocalTime class.

Let's suppose we have an instance of LocalTime :

LocalTime time = LocalTime.of(11, 45, 30); // 11:45:30

By using the following methods we can get hours, minutes, seconds, and nanoseconds a LocalTime instance:

time.getHour();   // 11
time.getMinute(); // 45
time.getSecond(); // 30
time.getNano();   // 0, nanoseconds

Another useful method is toSecondOfDay. It returns the time from the given LocalTime instance in seconds. For our example, 11:45:30 in seconds will be:

time.toSecondOfDay(); // 42330

Arithmetic methods of LocalTime

The class also has methods to add and subtract hours, minutes, seconds, and nanoseconds:

LocalTime time1 = time.plusHours(5); // 16:45:30
LocalTime time2 = time.plusHours(22); // 09:45:30
LocalTime time3 = time.minusMinutes(10); // 11:35:30
LocalTime time4 = time.minusSeconds(30); // 11:45

The following methods return a copy of an instance with one altered part:

LocalTime time1 = time.withHour(23); // 23:45:30
LocalTime time2 = time.withMinute(50); // 11:50:30
LocalTime time3 = time.withSecond(0); // 11:45

LocalDateTime

The LocalDateTime class is a combination of LocalDate and LocalTime that keeps values such as 2017-12-03T22:30. It still doesn't store information on a time-zone. It could be used to store a date and time of a transaction in a payment system. As in the LocalTime class, time is represented to nanosecond precision.

Creating LocalDateTime and current time

An instance of LocalDateTime that represents this current moment can be obtained using the now() method as shown below:

LocalDateTime now = LocalDateTime.now(); // this moment

The class has static methods of and parse to create instances:

LocalDateTime dt1 = LocalDateTime.of(2017, 11, 25, 22, 30);  // 25 November 2017, 22:30
LocalDateTime dt2 = LocalDateTime.parse("2017-11-25T22:30"); // 25 November 2017, 22:30

It's also possible to obtain an instance from the instances of LocalDate and LocalTime, like this:

LocalDate date = LocalDate.of(2017, 11, 25); // 2017-11-25
LocalTime time = LocalTime.of(21, 30); // 21:30
        
LocalDateTime dateTime = LocalDateTime.of(date, time); // 2017-11-25T21:30

or by using special instance methods of LocalDate and LocalTime:

LocalDate date = LocalDate.of(2017, 11, 25); // 2017-11-25
LocalTime time = LocalTime.of(21, 30); // 21:30       

LocalDateTime dateTime1 = date.atTime(time); // 2017-11-25T21:30
LocalDateTime dateTime2 = time.atDate(date); // 2017-11-25T21:30

LocalDateTime: from years to minutes

Now let's observe some methods of the LocalDateTime class. We've already created an instance dateTime to represent 25 of November, 2017, 10:30 pm:

LocalDateTime dateTime = LocalDateTime.of(2017, 11, 25, 22, 30); // 25 November 2017, 22:30

The class LocalDateTime has methods for obtaining units of date and time, such as a month, day of the month, hour and minute:

int month = dateTime.getMonthValue(); // 11
int day = dateTime.getDayOfMonth(); // 25
int hour = dateTime.getHour(); // 22
int minute = dateTime.getMinute(); // 30

The class also has instance methods toLocalDate and toLocalTime to get the date and time as the whole parts of LocalDateTime:

LocalDate dateOf = dateTime.toLocalDate(); // 2017-11-25
LocalTime timeOf = dateTime.toLocalTime(); // 22:30

Arithmetic methods of LocalDateTime

The LocalDateTime class has methods to add, subtract and alter years, months, days, hours, minutes, and seconds just like LocalDate and LocalTime. Let's explore them with a different example:

LocalDateTime endOf2017 = LocalDateTime.of(2017, 12, 31, 23, 59, 59); // 2017-12-31T23:59:59

This is how by adding one second we get into another year or move by years:

LocalDateTime beginningOf2018 = endOf2017.plusSeconds(1); // 2018-01-01T00:00
LocalDateTime beginningOf2020 = beginningOf2018.plusYears(2); // 2020-01-01T00:00

We can also alter the constituents of the LocalDateTime by indicating its values:

LocalDateTime beginningOf2020 = beginningOf2018.withYear(2020); // 2020-01-01T00:00

As you see, LocalDateTime is another immutable class from the java.time package. It represents a combination of LocalDate and LocalTime.

Comparing dates and time

The classes LocalDateLocalTime, and LocalDateTime have methods for comparing their instances according to their position on the timeline. The methods compare instances as they go in chronological order (or the order of time).

The compareTo method

The compareTo method compares this instance and another one passed as the method's argument. It returns 0 if they are equal, a negative value if this instance is less than the other, and a positive value if this instance is greater.

Here is an example of comparing two instances of the class LocalDate:

LocalDate date1 = LocalDate.parse("2017-01-02");
LocalDate date2 = LocalDate.parse("2017-12-12");

date1.compareTo(date1); // 0, date1 and date1 are equal
date1.compareTo(date2); // -11, negative value as date1 is less than date2
date2.compareTo(date1); // 11, positive value as date2 is greater than date1

The LocalTime class has the same method, that returns either 01 or -1:

LocalTime time1 = LocalTime.parse("15:30:10");
LocalTime time2 = LocalTime.parse("17:50:30");

time1.compareTo(time1); // 0, time1 and time1 are equal
time1.compareTo(time2); // -1, time1 is less than time2
time2.compareTo(time1); // 1, time2 is greater than time1

as well as LocalDateTime:

LocalDateTime dateTime1 = LocalDateTime.parse("2017-01-01T20:30"); // 1 January 2017, 20:30
LocalDateTime dateTime2 = LocalDateTime.parse("2017-01-02T23:00"); // 2 January 2017, 23:00

dateTime1.compareTo(dateTime1); // 0, dateTime1 and dateTime are equal
dateTime1.compareTo(dateTime2); // -1, dateTime1 is less than dateTime2
dateTime2.compareTo(dateTime1); // 1, dateTime2 is greater than dateTime1

Methods isAfter, isBefore and isEqual

The classes also provide some concise methods to compare dates and time on a timeline that return boolean value.

  • The isAfter method returns true only if this instance is strictly after the instance passed as the argument; otherwise, the method returns false.
  • The isBefore method returns true only if this instance is strictly before the instance passed as the argument; otherwise, the method returns false.
  • The isEqual method returns true if instances are equal; otherwise, the method returns false.

Check out this block of code where we compare two instances of the LocalDate class.

LocalDate date1 = LocalDate.of(2017, 11, 30);
LocalDate date2 = LocalDate.of(2017, 12, 1);

date1.isEqual(date1); // true
date1.isEqual(date2); // false

date1.isBefore(date2); // true
date1.isBefore(date1); // false
date2.isBefore(date1); // false

date2.isAfter(date1); // true
date2.isAfter(date2); // false
date1.isAfter(date2); // false

Here is an code samples where we compare two instances of the LocalTime class.

LocalTime time1 = LocalTime.of(14, 20); // 14:20
LocalTime time2 = LocalTime.of(15, 55); // 15:55
LocalTime time3 = LocalTime.of(16, 40); // 16:40
        
time1.isBefore(time2); // true
time3.isBefore(time2); // false
time3.isBefore(time3); // false

time2.isAfter(time1);  // true
time2.isAfter(time3);  // false

And here is an example where we compare two instances of the LocalDateTime class.

LocalDateTime dateTime1 = LocalDateTime.parse("2017-12-01T21:30"); // 1 December 2017, 21:30
LocalDateTime dateTime2 = LocalDateTime.parse("2017-12-02T21:30"); // 2 December 2017, 21:30

dateTime1.isEqual(dateTime2); // false
dateTime2.isEqual(dateTime2); // true

dateTime1.isBefore(dateTime2); // true
dateTime1.isAfter(dateTime2); // false
dateTime2.isAfter(dateTime1); // true

Keep in mind, that the LocalTime class doesn't have the isEqual method. You can use the equals method instead.

Create a free account to access the full topic

“It has all the necessary theory, lots of practice, and projects of different levels. I haven't skipped any of the 3000+ coding exercises.”
Andrei Maftei
Hyperskill Graduate