Core Java

Java 8 Period and Duration Example

In this article we will learn about the Duration and Period classes in Java. These classes were added in Java 8.

1. Introduction

A Duration measures an amount of time using time-based values (seconds, nanoseconds). A Period uses date-based values (years, months, days).

Duration

public final class Duration extends Object implements TemporalAmount, Comparable<Duration>, Serializable

 
A Duration represents a time-based amount of time, such as ‘34.5 seconds’. This class is immutable and thread-safe. This class models a quantity or amount of time in terms of seconds and nanoseconds. It can be accessed using other duration-based units, such as minutes and hours. In addition, the DAYS unit can be used and is treated as exactly equal to 24 hours, thus ignoring daylight savings effects.

A physical duration could be of infinite length. For practicality, the duration is stored with constraints similar to Instant. The duration uses nanosecond resolution with a maximum value of the seconds that can be held in a long. This is greater than the current estimated age of the universe.

The range of a duration requires the storage of a number larger than a long. To achieve this, the class stores a long representing seconds and an int representing nanosecond-of-second, which will always be between 0 and 999,999,999. The model is of a directed duration, meaning that the duration may be negative.

The duration is measured in “seconds”, but these are not necessarily identical to the scientific “SI second” definition based on atomic clocks. This difference only impacts durations measured near a leap-second and should not affect most applications. This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Duration may have unpredictable results and should be avoided. The equals method should be used for comparisons.

A Duration is most suitable in situations that measure machine-based time, such as code that uses an Instant object. A Duration object is 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. A Duration can have a negative value, if it is created with an end point that occurs before the start point.

A Duration is not connected to the timeline, in that it does not track time zones or daylight saving time. Adding a Duration equivalent to 1 day to a ZonedDateTime results in exactly 24 hours being added, regardless of daylight saving time or other time differences that might result.

Period

public final class Period extends Object implements ChronoPeriod, Serializable

A date-based amount of time in the ISO-8601 calendar system, such as ‘2 years, 3 months and 4 days’.
This class models a quantity or amount of time in terms of years, months and days. This class is immutable and thread-safe.

Durations and periods differ in their treatment of daylight savings time when added to ZonedDateTime. A Duration will add an exact number of seconds, thus a duration of one day is always exactly 24 hours. By contrast, a Period will add a conceptual day, trying to maintain the local time.

For example, consider adding a period of one day and a duration of one day to 18:00 on the evening before a daylight savings gap. The Period will add the conceptual day and result in a ZonedDateTime at 18:00 the following day. By contrast, the Duration will add exactly 24 hours, resulting in a ZonedDateTime at 19:00 the following day (assuming a one hour DST gap).

The supported units of a period are YEARS, MONTHS and DAYS. All three fields are always present, but may be set to zero. The ISO-8601 calendar system is the modern civil calendar system used today in most of the world. It is equivalent to the proleptic Gregorian calendar system, in which today’s rules for leap years are applied for all time.

The period is modeled as a directed amount of time, meaning that individual parts of the period may be negative. This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of Period may have unpredictable results and should be avoided. The equals method should be used for comparisons.

To define an amount of time with date-based values (years, months, days), use the Period class. The Period class provides various get methods, such as getMonths, getDays, and getYears, so that you can extract the amount of time from the period. The total period of time is represented by all three units together: months, days, and years. To present the amount of time measured in a single unit of time, such as days, you can use the ChronoUnit.between method.

2. Java 8 Period and Duration Example

In this section we will see some working example. First we will see some example of Duration. Let say we want to count the number of seconds between two given dates. First we will create the two LocalDateTime objects.

LocalDateTime oldDate = of(2018, Month.AUGUST, 31, 10, 20, 55);
LocalDateTime newDate = of(2018, Month.NOVEMBER, 9, 10, 21, 56);

A LocalDateTime represents a date-time without a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30.
LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value “2nd October 2007 at 13:45.30.123456789” can be stored in a LocalDateTime.

This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.

The ISO-8601 calendar system is the modern civil calendar system used today in most of the world. It is equivalent to the proleptic Gregorian calendar system, in which today’s rules for leap years are applied for all time. For most applications written today, the ISO-8601 rules are entirely suitable. However, any application that makes use of historical dates, and requires them to be accurate will find the ISO-8601 approach unsuitable.

This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of LocalDateTime may have unpredictable results and should be avoided. The equals method should be used for comparisons.

Now to see the number of seconds between these two time we do as below:

Duration duration = Duration.between(oldDate, newDate);
System.out.println(duration.getSeconds() + " seconds");

The Duration.between calculates the duration between two temporal objects. If the objects are of different types, then the duration is calculated based on the type of the first object. For example, if the first argument is a LocalTime then the second argument is converted to a LocalTime.
The specified temporal objects must support the SECONDS unit. For full accuracy, either the NANOS unit or the NANO_OF_SECOND field should be supported.
The result of this method can be a negative period if the end is before the start. To guarantee to obtain a positive duration call abs() on the result.

Now we will look at an example of using Period class. To calculate the difference between two dates you can use Period.between method as below:

LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(1988, Month.APRIL, 22);
Period p = Period.between(birthday, today);

Below is the full source code of the example:

DurationAndPeriod.java

package com.javacodegeeks.example;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;

import static java.time.LocalDateTime.of;

public class DurationAndPeriod {

    public static void main(String[] args) {
        durationExample();
        periodExample();
    }

    private static void durationExample() {
        Duration oneHours = Duration.ofHours(1);
        System.out.println(oneHours.getSeconds() + " seconds");

        // Test Duration.between
        System.out.println("### Duration.between ###");

        LocalDateTime oldDate = of(2018, Month.AUGUST, 31, 10, 20, 55);
        LocalDateTime newDate = of(2018, Month.NOVEMBER, 9, 10, 21, 56);

        System.out.println(oldDate);
        System.out.println(newDate);

        //count seconds between dates
        Duration duration = Duration.between(oldDate, newDate);

        System.out.println(duration.getSeconds() + " seconds");
    }

    public static void periodExample() {
        LocalDate today = LocalDate.now();
        LocalDate birthday = LocalDate.of(1988, Month.APRIL, 22);
        Period p = Period.between(birthday, today);
        System.out.println("### Period Example ###");
        System.out.println("You are " + p.getYears() + " years, " + p.getMonths() +
                " months, and " + p.getDays() +
                " days old.");
    }
}

3. Conclusion

In this article we learnt about the new two classes which were added in Java 8, namely Duration and Period. We discussed the difference between the two and also discussed the use-cases for them. Both these classes do similar kind of stuffs but they differ in the way you want the result.

4. Download the Source Code

Download
You can download the full source code of this example here: Java Duration and Period

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button