How do I use java.time.Instant class of Java Date-Time API?

The java.time.Instant class in the Java Date-Time API is an immutable representation of a point in time. It stores a long count of seconds from the epoch of the first moment of 1970 UTC, plus a number of nanoseconds for the further precision within that second.

The java.time.LocalDate class represents a date without a time or time zone. It is used to represent just a date as year-month-day (e.g., 2023-03-27) in the ISO-8601 calendar system.

The java.time.LocalTime class represents a time without a date or time zone. It is used to represent just a time as hour-minute-second (e.g., 13:45:20).

It’s also worth noting that Instant class is part of Java 8’s new date and time API which was brought in to address the shortcomings of the old java.util.Date and java.util.Calendar API.

Here’s a quick example of how to use the Instant class:

package org.kodejava.datetime;

import java.time.Instant;

public class InstantExample {
    public static void main(String[] args) {
        // Get the current point in time
        Instant now = Instant.now();
        System.out.println("Current time: " + now);

        // Add duration of 500 seconds from now
        Instant later = now.plusSeconds(500);
        System.out.println("500 seconds later: " + later);

        // Subtract duration of 500 seconds from now
        Instant earlier = now.minusSeconds(500);
        System.out.println("500 seconds earlier: " + earlier);

        // Compare two Instants
        int comparison = now.compareTo(later);
        if (comparison < 0) {
            System.out.println("Now is earlier than later");
        } else if (comparison > 0) {
            System.out.println("Now is later than later");
        } else {
            System.out.println("Now and later are at the same time");
        }
    }
}

Output:

Current time: 2024-01-18T09:26:56.152268Z
500 seconds later: 2024-01-18T09:35:16.152268Z
500 seconds earlier: 2024-01-18T09:18:36.152268Z
Now is earlier than later

In this example, Instant.now() is used to get the current Instant. Various methods like plusSeconds(), minusSeconds(), and compareTo() are used to manipulate and compare the Instant.

LocalDate and LocalTime are local in the sense that they represent date and time from the context of the observer, without a time zone.

To connect Instant with LocalDate and LocalTime, you need a time zone. This is because Instant is in UTC and LocalDate/LocalTime are in a local time zone, so you need to explicitly provide a conversion between them.

Here’s how you convert an Instant to a LocalDate and a LocalTime:

package org.kodejava.datetime;

import java.time.*;

public class InstantConvertExample {
    public static void main(String[] args) {
        Instant now = Instant.now();
        System.out.println("Instant: " + now);

        // Get the system default timezone
        ZoneId zoneId = ZoneId.systemDefault(); 

        LocalDate localDate = now.atZone(zoneId).toLocalDate();
        System.out.println("LocalDate: " + localDate);

        LocalTime localTime = now.atZone(zoneId).toLocalTime();
        System.out.println("LocalTime: " + localTime);
    }
}

Here Instant.now() gives the current timestamp. .atZone(ZoneId.systemDefault()) converts it to ZonedDateTime which is then converted to LocalDate and LocalTime by using .toLocalDate() and .toLocalTime() respectively.

You can also go from LocalDate and LocalTime back to Instant. Here’s how:

package org.kodejava.datetime;

import java.time.*;

public class ToInstantExample {
    public static void main(String[] args) {
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instantFromDateAndTime = LocalDateTime.of(localDate, localTime).atZone(zoneId).toInstant();

        System.out.println("Instant from LocalDate and LocalTime: " + instantFromDateAndTime);
    }
}

How do I use java.time.Duration class?

java.time.Duration is another useful class in Java for dealing with time. It measures time in seconds and nanoseconds and is most suitable for smaller amounts of time, like “20 seconds” or “3 hours”, and not for larger units like “3 days” or “4 months”. Here’s a guide on how to use it:

1. Creating a Duration instance

You can create an instance of Duration using one of its static factory methods that best suits your needs, such as ofSeconds(), ofMinutes(), ofHours(), or ofMillis().

//create a duration of 60 seconds
Duration duration = Duration.ofSeconds(60);

//create a duration of 2 hours
Duration twoHours = Duration.ofHours(2);

2. Creating a Duration between two Instants

Duration also provides a static method between() that can be used to find the duration between two points in time.

Instant start = Instant.now();
// Do some time consuming task...
Instant end = Instant.now();

Duration duration = Duration.between(start, end);

3. Retrieving the Duration

You can retrieve the number of days, hours, minutes, or seconds in a Duration using methods like toDays(), toHours(), toMinutes(), or getSeconds().

long hours = twoHours.toHours();  // returns 2

4. Adding and Subtracting from a Duration

Duration can be added or subtracted from another using the plus() and minus() methods or the more specific plus / minus methods such as plusHours(), minusMinutes(), etc.

// Adding
Duration additionalDuration = duration.plusHours(4);

// Subtracting
Duration lessDuration = additionalDuration.minusMinutes(50);

5. Comparing Durations

The Duration class provides compareTo(), equals(), negated(), and abs() methods for comparison:

Duration duration1 = Duration.ofHours(4);
Duration duration2 = Duration.ofHours(2);

// Returns a negative number, zero, or positive number if less than, 
// equal to, or greater than the other.
int comparison = duration1.compareTo(duration2);

boolean equals = duration1.equals(duration2); // false

// Returns a duration with the new duration being negative of this 
// duration.
Duration negated = duration1.negated(); 

// Returns a duration with the new duration being absolute of 
// this duration, effectively, it returns the same as duration1.
Duration abs = negated.abs();