How to get current date time with Java 8

 In this quick tutorial, we will see, how to get current date time using Java 8.


Java 8 had come up with new set of classes for date and time under java.time package, which are :

-  java.time.Instant

- java.time.ZonedDateTime

- java.time.OffSetDateTime

- java.time.LocalDateTime

Let us see how we can get current date and time using these classes and how they are different from each other.

Using Instant 

Instant represents a moment. For example, if World cup is starting at certain moment, it is exact that moment for everyone living in any part of world. If world cup is in Australia, then people in India can say that ,world cup started at different time than what what was time in Australia but it started at exact same moment on timeline for people of Australia as well as India. 

Using Instant, we can get the exact moment on timeline which is independent from time zones.

which in other words means that if two Instant objects are created at the same moment in any part of world, they will have exactly same value.

Instant represents date time in UTC(coordinated universal time), so it does not consider specific Zone and it is number of nanoseconds elapsed since epoch or since 1970-01-01T00:00:00Z. It is similar to GMT(Greenwich mean time).

All date times for specific Zones are calculated relative to UTC. 

For example : 
- A time in UTC (zone) itself, UTC + 0 is indicated by a Z( Z from Zulu time)
- Countries like Ireland, Portugal, Ghana follows UTC time zone, which means UTC + 0
- Japan follows UTC+9
- Barbados follows UTC-4

For complete list for all countries, you can check List of Countries with UTC time offsets

For our back end calculations in Java, we use Instant. For example, If we are running a job and want to calculate the time for next run we would use Instant. 

The reason of using Instant are:

Time Consistency Across Servers

Using UTC ensures that backend operations yield consistent results regardless of the specific time zone of the server, enhancing system reliability.

Simplified Daylight Saving Time Management

UTC does not adhere to daylight saving time adjustments, offering a straightforward solution for managing time operations consistently.

Log and Audit Integrity

When logging events or auditing actions, using UTC timestamps ensures consistency and ease of analysis, as there is no need to account for different time zones in log records.

Avoids Time Zone Confusion: 

When dealing with multiple time zones, using UTC can help avoid confusion and errors that can arise from converting times between various time zones. Developers can perform calculations and comparisons without worrying about different time zone conversions.

Now coming back to current date time using Instant, we need to use now() method as below :
Instant instant = Instant.now();
System.out.println("Current Date Time using Instant:" + instant);
Output:
Current Date Time using Instant:2021-01-09T22:25:06.385917300Z

Using ZonedDateTime

If you want to know date time, in your time zone, at a particular moment( represented by Instant) you can use ZonedDateTime.

You can either adjust the instant created above to get the ZonedDateTime like below :

Adjusting Instant object :

System.out.println("Using instant.atZone():" + instant.atZone(ZoneId.of("Europe/Amsterdam")));
Output:
Using instant.atZone():2021-01-09T23:25:06.385917300+01:00[Europe/Amsterdam]
This gives me exact date time in Amsterdam.

Using now(ZoneId zoneId) :

Alternatively you can use factory method now(ZoneId zoneId) defined in ZonedDateTime class itself like below:
System.out.println("Using ZonedDateTime.now(zoneId):" + ZonedDateTime.now(ZoneId.of("Europe/Amsterdam")));
Output:                                                                       Using ZonedDateTime.now(zoneId):2021-01-09T23:25:06.408922700+01:00[Europe/Amsterdam]

Using now() :

And there is one more option where in you can use factory method now() of ZonedDateTime class. However you must know that now() uses the default time zone of your JVM, which is subject to change, so better always pass zoneId.
System.out.println("ZonedDateTime with now():" + ZonedDateTime.now());
Output:                                                                       Using ZonedDateTime.now():2021-01-09T23:25:06.414919900+01:00[Europe/Berlin]
Another variant of now() is like below for using default time zone using ZoneId.systemDefault() as ZoneId.
System.out.println("Using ZonedDateTime.now(ZoneId.systemDefault())" + ZonedDateTime.now(ZoneId.systemDefault()));
Output:                                                                       Using ZonedDateTime.now(ZoneId.systemDefault()):2021-01-09T23:25:06.414919900+01:00[Europe/Berlin]

ZonedDateTime supports Day Light Savings

ZonedDateTime uses ZoneRules to determine how an offset varies for a particular time zone in case of Day light saving.

Lets take an example. Day light saving in Netherlands in 2021 is going to start from March 28, 2:00 AM and will end on October 31, 3:00 AM

Let us first try to see date time before(by 1 hour) Day light saving starts, i.e. at 1 AM
System.out.println("ZonedDateTime.of() before DLS: " + ZonedDateTime.of(2021, 3, 28, 1, 0, 0,0, ZoneId.of("Europe/Amsterdam")));
Output:
ZonedDateTime.of() before DLS: 2021-03-28T01:00+01:00[Europe/Amsterdam]

As you can see, it returned the time which we have asked for i.e. 1 AM and offset is of +1:00

Now let us try to see date time at the time when Day light saving is going to start i.e. at 2 AM.
System.out.println("ZonedDateTime.of() DLS start: " + ZonedDateTime.of(2021, 3, 28, 2, 0, 0,0, ZoneId.of("Europe/Amsterdam")));
Output                                                               ZonedDateTime.of() DLS start: 2021-03-28T03:00+02:00[Europe/Amsterdam]

As you can see , ZonedDateTime API automatically adjusted the time and returned time which is 1 hour ahead i.e. 3 AM instead of 2 AM and also now Offset is set to +2:00.

Using OffsetDateTime

OffsetDateTime represents a moment in date time which is some duration ahead(+) or behind(-) the UTC or in other words with offset from UTC without a Time ZoneId such as "Europe/Amsterdam".

You can use ZoneOffset class to represent offset in hours, hours: minutes or hours: minutes: seconds.

So if the OffSet is zero, then OffsetDatTime represents Instant, which is in UTC.
System.out.println("Using OffsetDateTime.now():" + OffsetDateTime.now());
Output:                                                                       Using OffsetDateTime.now():2021-01-09T23:25:06.415920100+01:00

Using LocalDateTime

LocalDateTime gives you date time without any offset(from UTC) information or any Zone information, which in other words means it can not represent moment on the timeline.
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime is:" + localDateTime);
Output:
localDateTime is:2021-01-09T23:25:06.416918700

Summary

- There are multiple way you can get hold of current date time using Java 8 API depending upon your requirements.
- Instant gives you moment on timeline and gives you date time in UTC and does not consider time zone.
- Any two instances of Instant created at same moment in any part of world will give you same objects, which means they represents the same moment on the timeline.
- You can use ZonedDateTime class for date time with Offset from UTC and Zone information.
- You can use OffsetDateTime to get date time with OffSet from UTC.
- You can use LocalDateTime ,if you want to get date time as shown on your clock.