8.3.  Define, create, and manage date- and time-based events using Instant, Period, Duration, and TemporalUnit

[Note]

Instant

An instant is a point representing a unique moment in time on a timeline. An epoch is an instant on a timeline that is used as a reference point (or the origin) to measure other instants.

An object of the Instant class represents an instant on the timeline. It uses a timeline to represent simplified UTC to a nanosecond precision. The timeline uses 1970-01-01T00:00:00Z as the epoch. Instants after the epoch have positive values; instants before the epoch have negative values. The instant at the epoch is assigned a zero value.

There are different ways you can create an instance of the Instant class:

Instant inst1 = Instant.now(); // get the current instant
System.out.println(inst1.getEpochSecond());

Instant inst2 = Instant.EPOCH; // get the epoch
System.out.println(inst2.getEpochSecond());

Instant inst3 = Instant.ofEpochSecond(10); // get 10 seconds after the epoch
System.out.println(inst3.getEpochSecond());
					

output

1445236914
0
10
					

You can record the current instant with the given Clock instance for the specific time-zone:

// get clock with desired time-zone
Clock clock = Clock.system(ZoneId.of("America/Chicago"));

Instance now = Instant.now(clock);
					

The toString() method of the Instant class returns a textual representation of the instance in the ISO-8601 format yyyy-MM-ddtHH:mm:ss.SSSZ:

Instant inst1 = Instant.now();
System.out.println(inst1);
					

2015-10-19T06:41:54.170Z
					

Duration

An object of the Duration class represents an amount of time between two instants on the timeline. The Duration class supports a directed duration.

You can add (and subtract) a duration to an instant to obtain another instant.

Instant now = Instant.now();
Duration d = Duration.ofHours(1);
Instant then = now.plus(d);
System.out.println("now : " + now + " ; then : " + then);
					

now : 2015-10-19T20:21:52.510Z ; then : 2015-10-19T21:21:52.510Z
					

Adding two durations results in another duration:

Duration d1 = Duration.ofHours(1);
Duration d2 = Duration.ofDays(2);
d1 = d1.plus(d2);
System.out.println("Total duration : " + d1);
					

Total duration : PT49H
					

The toString() method of the Duration class returns a textual representation of the duration in PTnHnMnS format, where n is the number of hours, minutes, or seconds.

[Important]

Duration can only handle fixed-length periods, such as "hours", "minutes", "seconds", "days" (where it assumes exactly 24 hours per day). You can't use "months" with Duration, because a month varies in length.

Period

The Period class represents an arbitrary amount of time in years, months, and days. Period objects can be particularly useful for adding/subtracting time to/from a date. For example:

LocalDate today = LocalDate.parse("2015-10-19");
Period sixDays = Period.ofDays(7);
LocalDate nextWeek = today.plus(sixDays);
System.out.println("next week : " + nextWeek);
					

next week : 2015-10-26
					

The Period class also offers a static method Period.between(...) that is great for determining elapsed time between dates:

LocalDate newYear = LocalDate.parse("2015-01-01");
Period passed = Period.between(newYear, today);
System.out.println("passed since NY : " + passed);
					

passed since NY : P9M18D
					

The toString() method of the Period class returns a textual representation of the period in PnYnMnD format, where n is the number of years, months, or days. Also there could be nW representation, where n is the number of weeks.

[Important]

The difference between a period and a duration is: when someone mentions a 2 month period, you do not know the exact amount of nanoseconds in that 2 months. A 2 month period may mean different number of days (and hence different nanoseconds) depending on when that period starts. So, for this case only the Period class suits.

Duration is the most suitable when we measure machine based timings, where as Period is the most suitable when we want to know the human readable time representation.

TemporalUnit

The TemporalUnit is an interface which defines a unit of date-time, such as Days or Hours.

The most commonly used units are defined in ChronoUnit enumeration. This enum replaces integer values used in old API to represent day, month, year, week, decade, etc.

LocalDate today = LocalDate.now();
System.out.println("Today: " + today);

LocalDate twoWeeksLater = today.plus(2, ChronoUnit.WEEKS);
System.out.println("Two weeks later: " + twoWeeksLater);
					

output:

Today: 2015-10-23
Two weeks later: 2015-11-06
					

The ChronoUnit can be used to truncate timestamps (e.g. Instant or LocalDateTime) to different precision with Xxx.truncatedTo(TemporalUnit) method. The method returns a copy of the original timestamp object with fields smaller than the specified unit set to zero. For example, truncating with the ChronoUnit.MINUTES unit will round down to the nearest minute, setting the seconds and nanoseconds to zero:

LocalDateTime ldtStart = LocalDateTime.of(2015, 10, 23, 12, 7, 1);
LocalDateTime ldtEnd   = LocalDateTime.of(2015, 10, 23, 15, 8, 2);

LocalDateTime ldtStartNew = ldtStart.truncatedTo(ChronoUnit.MINUTES);
System.out.println("Start time truncated to minutes : " + ldtStartNew);

LocalDateTime ldtEndNew = ldtEnd.truncatedTo(ChronoUnit.HOURS);
System.out.println("End time truncated to hours : " + ldtEndNew);
					

output:

Start time truncated to minutes : 2015-10-23T12:07
End time truncated to hours : 2015-10-23T15:00
					

The ChronoUnit can also be used to calculate time periods along with Duration and Period classes. The Duration measures time like time-based values like seconds, minutes, hours etc. Use Duration to find machine-based time, with Instant object. The Period is useful to measure an amount of time with date-based values like years, months, days. You can get the amount of time in days, months, years with the getXxx() methods from a Period of time.

The ChronoUnit.between(...) method is useful when you want to measure an amount of time in a single unit of time, such as days or seconds:

LocalDateTime ldtStart = LocalDateTime.of(2015, 10, 23, 12, 7, 1);
LocalDateTime ldtEnd   = LocalDateTime.of(2015, 10, 23, 15, 8, 2);

long numberOfHours = ChronoUnit.HOURS.between(ldtStart, ldtEnd);
System.out.println("Between in hours : " + numberOfHours);

long numberOfMinutes = ChronoUnit.MINUTES.between(ldtStart, ldtEnd);
System.out.println("Between in minutes : " + numberOfMinutes);
					

output:

Between in hours : 3
Between in minutes : 181
					

The ChronoUnit.between(..) accepts not only LocalDateTime,but also the classes which implements Temporal interface like Instant, ZonedDateTime, LocalDate, LocalTime, OffsetDateTime, OffsetTime, Year, YearMonth, etc.

Professional hosting         Free 'Oracle Certified Expert Web Services Developer 6' Guide     Exam 1Z0-810: Upgrade to Java SE 8 Programmer Quiz