Introduction to JAVA8 Date/Time API
Tags: java8, api, date, time
Published: 2020-05-23 16:17:06

Java 8 was released in March 2014 and brought a lot of language improvements. One of those is new Date and Time API for Java, also known as JSR-310. It represents a very rich API for working with dates and time.

**Issues with java.util.Date and java.util.Calendar:**
* A Date instance represents an instant in time, not a date.
* It rates years as two digits since 1900.
* Months are zero indexed (0 – January, 11 – December).
* All classes in this old API are mutable, and not thread safe. 

**New Java8 Date/Time API:**
* Thread Safety: the new Date and Time APIs introduced in Java 8 are immutable and thread safe,
* Domain-driven design: The new API models its domain very precisely with classes that represent different use cases for Date and Time closely
* ZonedDate and Time: handling of timezone can be done with Local and ZonedDate/Time APIs.

**java.time.LocalDate :**
* represents date without timezone.
* immutable object and thread-safe.
* it follows ISO-8601 calendar system (https://www.iso.org/iso-8601-date-and-time-format.html).

we can create LocalDate objects using one of the following its static methods: 
 ```java
 LocalDate nowDate = LocalDate.now(); //Obtains the current date from the system clock in the default time-zone.       
 LocalDate date  = LocalDate.of(int year, int month, int day); //January is equivalent to 1 
```

we can also create LocalDate from a String:
```java
 LocalDate date = LocalDate.parse("2012-01-26"); // default format is yyyy-MM-dd
```
the most common useful methods :
```java
 LocalDate date  = LocalDate.of(2020, 01, 01);

 date.plusDays(2);
 date.plusMonths(3L);
 date.plusWeeks(1);
 date.plusYears(12);

 date.minusDays(2L);
 date.minusMonths(3);
 date.minusWeeks(1L);
 date.minusYears(12);

 date.isLeapYear();
 date.isBefore(LocalDate.now());
 date.isAfter(LocalDate.now());

 date.getDayOfMonth(); // day of month is 1-index
 date.getDayOfWeek();  // returns DayOfWeek enum
 date.getDayOfYear();  // day of year is 1-index
```


**java.time.LocalTime :**
* LocalTime is an immutable date-time object that represents a time.
* This class is immutable and thread-safe.
* time without a time-zone.
* it follows ISO-8601 calendar system 

we can create LocalTime objects using one of the following its static methods: 

```java
 LocalTime.now();
 LocalTime.of(int hour, int minute);
 LocalTime.of(int hour, int minute, int second);
 LocalTime.of(int hour, int minute, int second, int nanoOfSecond);
 LocalTime.parse("12:05:12:001");

```

the most common useful methods :

```java
 LocalTime time = LocalTime.now();

 time.getMinute(); 
 time.getHour();  
 time.getSecond();
 time.getNano();

 time.isAfter(LocalTime.now());
 time.isBefore(LocalTime.now());

 time.minusHours(2L); 
 time.minusMinutes(1L);
 time.minusSeconds(10);
 time.minusNanos(23);

 time.plusHours(2L);
 time.plusMinutes(1L);
 time.plusSeconds(10);
 time.plusNanos(23);

```

**java.time.LocalDateTime :**

* represents a combinaison of date and time.
* immutable object and thread safe.
* It follow ISO-8601.

we can create LocalTime objects using one of the following its static methods: 

```java
  LocalDateTime dateTime = LocalDateTime.now();
  LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute);
  LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second);
  LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) ;
  LocalDateTime.of(LocalDate date, LocalTime time); 
```

**Method chaining :**
chaining method is an very useful technic that used with immutable objects to write clear and clean code and more concise, and avoid multi statements code.

```java
int dayOfYear = LocalDate.of(2,2, 2022)
                .minusDays(2)
                .plusWeeks(4)
                .minusMonths(4)
                .getDayOfYear();
```

**java.time.Period :**

A date-based amount of time in the ISO-8601 calendar system, such as '2 years, 3 months and 4 days'.

The total period of time is represented by all three units together: months, days, and years.

The Date can be manipulated using Period as shown in the following code snippet:
```java
  LocalDate  initialDate = LocalDate.parse("2020-02-25");
  LocalDate endDate = initialDate.plus(Period.ofDays(4));
  Period difference = Period.between(initialDate, endDate);
```
if we are going to use the same multiple times, we can create an object Period and reused:
```java
  // Period of 5 years, 4 months, and 2 days
   Period period = Period.of(5, 4 , 2);
```

**java.util.Duration :**
Similar to Period, the Duration class is use to deal with Time.
A time-based amount of time, such as '34.5 seconds'. 

in this example we create an LocalTime object 4:5:45am and add 30 seconds to it.
```java
  LocalTime initialTime = LocalTime.of(4, 5, 45);
  LocalTime endTime = initialTime.plus(Duration.ofSeconds(43));
```

The Duration between two instants can be obtained as a Duration:
```java
   Duration difference = Duration.between(initialTime, endTime);
   long seconds = difference.getSeconds();
```
**java.time.Instant:**
the class stores a long representing epoch-seconds and an int representing nanosecond-of-second, which will always be between 0 and 999,999,999.

The instant is defined as an offset since the origin (called an epoch). The origin is Jan. 1st 1970 - 00:00 - Greenwhich mean time (GMT).

```java
Instant instant = Instant;
System.out.println(instant);
```
we can create an LocalDateTime from an instant as following, but we need a timeZone also:
```java
Instant instant = Instant.now();
LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
```

**From java.util.Date to a LocalDateTime:**
Java8 added the method toInstant() to Date object which help us to convert a Date  or Calendar to the new java date/time api, let's see how:
```java
Date date = new Date();
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());       
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
```
**Date and Time Formatting :**
Java 8 provides APIs for the easy formatting of Date and Time.

the code below shows default date format:
```java
LocalDateTime localDateTime = LocalDateTime.of(2019, 06, 19, 12, 05, 23);
System.out.println(localDateTime);
```
its output is:
```java
2019-06-19T12:05:23
```
also we can use predefined ISO format:
```java
LocalDateTime localDateTime = LocalDateTime.of(2019, 06, 19, 12, 05, 23);
String  localDateTimeString = localDateTime.format(DateTimeFormatter.ISO_DATE);
System.out.println(localDateTimeString);
```
the output is : 
```java
2019-06-19
```

we can create our format as following :
```java
LocalDateTime localDateTime = LocalDateTime.of(2019, 06, 19, 12, 05, 23);   
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/yyyy/MM");
String  localDateTimeString = localDateTime.format(dateTimeFormatter);
System.out.println(localDateTimeString);
```
output is :
```java 
19/2019/06
```