Java 8 Date and Time

Java 8 Date Time API

With Java 8, a new Date-Time API is introduced to cover the following drawbacks of old date-time API.

Thread safety
Old java.util.Date is not thread safe, thus programmers have to deal with concurrency issue while using old API.
The new date-time API is immutable and does not have setter methods.

Design constraint
Default Date starts from 1900, month starts from 1, and day starts from 0, so no uniformity.
The old API had less direct methods for date operations. The new API provides numerous utility methods for such operations.

Simplified time zone handling
Developers had to write a lot of code to deal with timezone issues. The new API has been developed keeping domain-specific design in mind.

Java 8 New Date and Time API

Java 8 introduces a new date-time API under the package java.time.

Following are some of the important classes introduced in java.time package.

Local − Simplified date-time API with no complexity of timezone handling.
Zoned − Specialized date-time API to deal with various timezones.

LocalDateTime, LocalDate, and LocalTime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Get the current date and time
LocalDateTime currentDateTime = LocalDateTime.now();
System.out.println("Current DateTime: " + currentDateTime); //Print both date and time in format YYYY-MM-DDTHR:MI:SEC.MS

LocalDate date = currentTime.toLocalDate(); //Convert to LocalDate object
System.out.println("Extracting date from LocalDateTime.toLocalDate(): " + date); //Print date in format of YYYY-MM-DD

Month month = currentDateTime.getMonth();
int day = currentDateTime.getDayOfMonth();
int seconds = currentDateTime.getSecond();

Syste.out.println("Extracting Month from LocalDateTime.getMonth(): " + month +"day: LocalDateTime.getDayOfMonth() " + day +"seconds: LocalDateTime.getSecond()" + seconds)

//Changing the currentTime with new Day and Month.
LocalDateTime modifiedDate = currentDateTime.withDayOfMonth(10).withYear(2012);
System.out.println("Modified date on currentdate object: " + modifiedDate);

//Create a custome date object using LocalDate.of- 12 december 2014
LocalDate customeDate = LocalDate.of(2014, Month.DECEMBER, 12);
System.out.println("date3: " + customeDate);

//Create a custome time object using LocalTime.of
LocalTime localTime = LocalTime.of(22, 15);
System.out.println("localTime: " + localTime);

//parse a string
LocalTime customTime = LocalTime.parse("20:15:30");
System.out.println("customTime: " + customTime);
Zone dependent Date and time API
1
2
3
4
5
6
7
8
9
10
11
12
13
// Get the current date and time
ZonedDateTime zoneSpecificDate = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Kolkata]");
System.out.println("Zone dependent data and time : " + zoneSpecificDate);
System.out.println("Zone of the date is " + zoneSpecificDate.getZone());

ZoneId id = ZoneId.of("Europe/Paris"); //Creating zone object
System.out.println("ZoneId: " + id);

ZoneId currentZone = ZoneId.systemDefault();
System.out.println("CurrentZone: " + currentZone);

ZonedDateTime zonedDatetime = ZonedDateTime.now();
System.out.println("Zoned datetime now " + zonedDatetime);
Chrono Units Enum

java.time.temporal.ChronoUnit enum is added in Java 8 to replace the integer values used in old API to represent day, month, etc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Get the current date
LocalDate today = LocalDate.now();
System.out.println("Current date: " + today);

//add 1 week to the current date
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
System.out.println("Next week: " + nextWeek);

//add 1 month to the current date
LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS);
System.out.println("Next month: " + nextMonth);

//add 1 year to the current date
LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
System.out.println("Next year: " + nextYear);

//add 10 years to the current date
LocalDate nextDecade = today.plus(2, ChronoUnit.DECADES);
System.out.println("Date after two of the ten year: " + nextDecade);

//Next century today's date
LocalDate nextCentury = today.plus(1, ChronoUnit.CENTURIES);
System.out.println("Date after 100 years " + nextCentury);

System.out.println("two week back date is " + today.minusWeeks(2));

Duration and Period

With Java 8, two specialized classes are introduced to deal with the time differences.

Period − It deals with date based amount of time.
Duration − It deals with time based amount of time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Get the current date
//Period example - Date based amount of time
LocalDate today = LocalDate.now();
System.out.println("Current date: " + today);

//add 1 month to the current date
LocalDate dayAfterMonth = today.plus(1, ChronoUnit.MONTHS);
System.out.println("Next month: date : " + dayAfterMonth);

Period period = Period.between(dayAfterMonth, today);
System.out.println("Period: " + period);

##### Duration - Time based interval
LocalTime timeNow = LocalTime.now();
Duration twoHours = Duration.ofHours(2);

LocalTime timeAfterTwoHour = timeNow.plus(twoHours);
Duration duration = Duration.between(timeNow, timeAfterTwoHour);

System.out.println("Duration: " + duration);

Temporal Adjusters

TemporalAdjuster is used to perform the date mathematics. For example, get the “Second Saturday of the Month” or “Next Tuesday”.

1
2
3
4
5
6
7
8
9
10
11
12
13
//Get the current date
LocalDate today = LocalDate.now();
System.out.println("Current date: " + today);

//get the next tuesday
LocalDate nextTuesday = today.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
System.out.println("Next Tuesday on : " + nextTuesday);

//get the second saturday of next month
LocalDate firstInYear = LocalDate.of(today.getYear(),today.getMonth(), 1);
LocalDate secondSaturday = firstInYear.with(TemporalAdjusters.nextOrSame(
DayOfWeek.SATURDAY)).with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
System.out.println("Second Saturday on : " + secondSaturday);

Backward compatibility with Date/Time API

A toInstant() method is added to the original Date and Calendar objects, which can be used to convert them to the new Date-Time API. Use an ofInstant(Insant,ZoneId) method to get a LocalDateTime or ZonedDateTime object.

1
2
3
4
5
6
7
8
9
10
11
12
13
//Get the current date
Date currentDate = new Date();
System.out.println("Current date: " + currentDate);

//Get the instant of current date in terms of milliseconds
Instant now = currentDate.toInstant();
ZoneId currentZone = ZoneId.systemDefault();

LocalDateTime localDateTime = LocalDateTime.ofInstant(now, currentZone);
System.out.println("Local date: " + localDateTime);

ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(now, currentZone);
System.out.println("Zoned date: " + zonedDateTime);