Get up to 80 % extra points for free! More info:

Lesson 13 - Date and Time in Java - Modifying and intervals

In the previous lesson, Date and Time in Java - Creating and formatting, we learned to create LocalDate, LocalTime, and LocalDateTime instances and format their value. In today's tutorial of our Java course, we're going to modify the value and introduce time intervals.

Conversions

First of all, we'll learn how to convert between the LocalDate, LocalTime, and LocalDateTime data types.

Converting from LocalDateTime

We convert from LocalDateTime easily by using the toLocalDate() and toLocalTime() methods.

Converting to LocalDateTime

We create LocalDateTime instances using one of the of*() methods where we specify the date and time separately:

LocalDate halloween = LocalDate.of(2017, 10, 31);
LocalDateTime dateTime = LocalDateTime.of(halloween, LocalTime.of(10, 0));

If we want to set the time at the very beginning of the day, we can use the atStartOfDay() method. Another method, which allows us to take a date and attach a time to it, is atTime(). Here’s an alternative approach for the example above:

LocalDate halloween = LocalDate.of(2017, 10, 31);
LocalDateTime dateTime = halloween.atStartOfDay();
LocalDateTime dateTime2 = halloween.atTime(0, 0);

Modifying the value

We can add a particular number of days, hours and so on to an existing instance. We use the methods with the plus...() or minus...() prefix to do just that. I'm sure we don't have to explain which does what. The important thing to remember is that they return a new instance with the modified value. The instance is completely immutable (unchangeable) and any changes are made by replacing the original instance with a new one (as we do with Strings).

Here’s an example where we add three more days to the current date:

LocalDateTime dateTime = LocalDateTime.now();
dateTime = dateTime.plusDays(3);
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));

The result:

Console application
Dec 9, 2016

Here's a list of the available methods:

  • minusDays()
  • minusHours()
  • minusMinutes()
  • minusMonths()
  • minusNanos()
  • minusSeconds()
  • minusWeeks()
  • minusYears()
  • plusDays()
  • plusHours()
  • plusMinutes()
  • plusMonths()
  • plusNanos()
  • plusSeconds()
  • plusWeeks()
  • plusYears()

Periods and Durations

Aside from the methods we've already mentioned, there are also four general minus() and plus() methods which receive an interval that is to be added or subtracted. They come in handy when we don't know whether we're going to add days or years at a specific point in the application, so they spare us from having to implement complex branching. There are also Duration and Period classes available, which provide us objects representing time intervals.

When we get to interfaces, you can check that both classes implement the TemporalAmount interface. However, don't worry about it too much for now.

Here’s a modified version of the example code from before:

LocalDateTime dateTime = LocalDateTime.now();
dateTime = dateTime.plus(Period.ofDays(3));
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));

The output will remain the same as with the previous example. The of...*() methods have the same suffixes as the plus()/minus() methods listed above.

The Difference between Period and Duration is that Duration represents a time interval which isn't related to the calendar anyhow (e.g. how long it takes to manufacture a car), a day always lasts 24 hours there. Whereas, Period also takes daylight saving time into consideration, so a day may sometimes be 23 or 25 hours long. We use Period to work with LocalDate/Local­DateTime and Duration to work exclusively with time.

ChronoUnit

To make units (such as days, hours, minutes and similar) easier to work with, there's the ChronoUnit class. It uses the Duration class internally, so all it provides is a different syntax for the tasks we demonstrated above. For completeness' sake, we'll go over an example of its use:

LocalDateTime dateTime = LocalDateTime.now();
dateTime = dateTime.plus(3, ChronoUnit.DAYS);
System.out.println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));

Note.: ChronoUnit implements the TemporalUnit interface, in case you need it later on. We'll introduce interfaces later in the course.

As you can see, the implementation of date and time in Java is quite complex. We won't go into unnecessary details. Instead, we'll focus on practical use, as we always do here at ICT.social.

Between()

The last method worth mentioning is the static between() method in the Period class. It allows us to compute the difference (interval) between 2 dates. More accurately, it computes the difference between two objects implementing the Temporal interface, which is the common data type for the LocalDate, LocalDateTime, and LocalTime classes.

LocalDate started = LocalDate.of(1939, 9, 1);
LocalDate ended = LocalDate.of(1945, 9, 2);
TemporalAmount period = Period.between(started, ended);
System.out.println("The World War II lasted for " + period.get(ChronoUnit.YEARS) + " years and " + period.get(ChronoUnit.DAYS) + " days");

The output:

Console application
The World War II lasted for 6 years and 1 days

The same method is available in the Duration class, however, that one works with LocalDateTime rather than LocalDate. We wouldn’t be able to extract the number of years from an interval since years don't have a fixed amount of days and Duration isn't related to calendar-based time.

Setting the value

We set the value using the with...*() methods, they all have the same suffixes as the methods mentioned earlier. As always, remember that they only return a new instance and don't modify the current one.

LocalDate started = LocalDate.of(1939, 9, 1);
started = started.withMonth(10); // Sets the month to 10

Method chaining

The fact that all of the methods return new instances, so as to keep classes immutable, also allows us to use the fluent interface, aka "method chaining". It really isn’t all that complicated, all it means is that we’re able to call multiple methods on a single line.

Let's set the value for programmer Christmas, i.e. Halloween (since, 31 OCT = 25 DEC).

LocalDate started = LocalDate.of(1939, 9, 1);
started = started.withMonth(10).withDayOfMonth(31);

We'll continue in the next lesson, Date and Time in Java - Parsing and comparing, where we'll finish up with date and time in Java. We'll learn how to parse date and time and how to access inner values.


 

Previous article
Date and Time in Java - Creating and formatting
All articles in this section
Object-Oriented Programming in Java
Skip article
(not recommended)
Date and Time in Java - Parsing and comparing
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities