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
You can download the full source code of this example here: Java Duration and Period