A big part of the developer community had complained about Date and Calendar classes. The reasons were many such as hard to understand, hard to use, and not being flexible. Date class had become obsolete, and java docs suggested using Calendar class. And on top of all, date comparison was buggy.
Moving forward, Java 8 is expected to release the new Date and Time APIs/classes (JSR-310), called ThreeTen, which will change how you have been handling dates in Java. This A key part of this is providing a new API that is dramatically easier to use and less error prone.
It will provide some highly demanded features such as:
- All the core public classes are immutable and thread-safe
- Defined terminology and behavior that other areas in computing can adapt
1. Core Classes to Represent Date and Time
The new classes intended to replace Date class are
The LocalDate class represents a date. There is no representation of a time or time zone.
LocalDate localDate = LocalDate.now(); System.out.println(localDate.getDayOfWeek().toString()); //WEDNESDAY System.out.println(localDate.getDayOfMonth()); //15 System.out.println(localDate.getDayOfYear()); //135 System.out.println(localDate.isLeapYear()); //false
The LocalTime class represents a time. There is no representation of a date or time zone.
//LocalTime localTime = LocalTime.now(); //toString() in format 09:57:59.744 LocalTime localTime = LocalTime.of(12, 20); System.out.println(localTime.toString()); //12:20 System.out.println(localTime.getHour()); //12 System.out.println(localTime.getMinute()); //20 System.out.println(localTime.getSecond()); //0 System.out.println(localTime.MIDNIGHT); //00:00 System.out.println(localTime.NOON); //12:00
The LocalDateTime class represents a date-time. There is no representation of a time zone. It represents the date and time in the current time zone.
LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime.toString()); //2013-05-15T10:01:14.911 System.out.println(localDateTime.getDayOfMonth()); //15 System.out.println(localDateTime.getHour()); //10 System.out.println(localDateTime.getNano()); //911000000
1.4. OffsetDateTime and ZonedDateTime
If you want to use the date functionality with timezone information, then the new API provides 2 classes similar to the above one i.e. OffsetDateTime and ZonedDateTime.
- OffsetDateTime represents the date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system.
- ZonedDateTime represents the date-time with a time-zone in the ISO-8601 calendar system.
OffsetDateTime offsetDate = OffsetDateTime.now(); System.out.println(offsetDate); //2023-02-07T15:10:46.260589600+05:30 ZonedDateTime zonedDateTime = ZonedDateTime.now(); System.out.println(zonedDateTime); //2023-02-07T15:10:46.260589600+05:30[Asia/Calcutta]
2. Core Classes to Represent Timestamp and Duration
The new API has separate classes to denote the timestamp in the current timezone and in a specified timezone. We also have separate classes to denote the difference between the two dates in a consistent manner.
For representing the specific timestamp at any moment, we use Instant. The
Instant class represents an instant in time to an accuracy of nanoseconds. Operations on an
Instant include the comparison to another
Instant and adding or subtracting a duration.
Instant instant = Instant.now(); System.out.println(instant.toString()); //2013-05-15T05:20:08.145Z System.out.println(instant.plus(Duration.ofMillis(5000)).toString()); //2013-05-15T05:20:13.145Z System.out.println(instant.minus(Duration.ofMillis(5000)).toString()); //2013-05-15T05:20:03.145Z System.out.println(instant.minusSeconds(10).toString()); //2013-05-15T05:19:58.145Z
The Duration class is a whole new concept brought first time in java language. It represents the time difference between two timestamps.
Duration duration = Duration.ofMillis(5000); Duration duration = Duration.ofSeconds(60); Duration duration = Duration.ofMinutes(10); Duration duration = Duration.ofHours(2); Duration duration = Duration.between(Instant.now(), Instant.now().plus(Duration.ofMinutes(10)));
Duration deals with small units of time such as milliseconds, seconds, minutes and hours. They are more suitable for interacting with application code.
To interact with humans, you need to get bigger durations presented with Period class.
Period period = Period.ofDays(6); Period period = Period.ofMonths(6); Period period = Period.between(LocalDate.now(), LocalDate.now().plusDays(60));
3. Utility Classes and Enums
The current Java SE platform uses int constants for months, day-of-week and am-pm etc. Now a lot of extra utility classes have been added that work on top of these enums. We are taking an example of such a class DayOfWeek. This class is a wrapper of day enums and can be used consistently with other classes.
Other such classes are
YearMonth and many more.
//day-of-week to represent, from 1 (Monday) to 7 (Sunday) System.out.println(DayOfWeek.of(2)); //TUESDAY DayOfWeek day = DayOfWeek.FRIDAY; System.out.println(day.getValue()); //5 LocalDate localDate = LocalDate.now(); System.out.println(localDate.with(DayOfWeek.MONDAY)); //2013-05-13 i.e. when was monday in current week ?
4. Date Adjusters
Date adjusters are another beautiful and useful addition to date-handling tools. It easily solves the problems like: How do you find the last day of the month? Or the next working day? Or a week on Tuesday?
LocalDate date = LocalDate.of(2013, Month.MAY, 15); //Today LocalDate endOfMonth = date.with(TemporalAdjusters.lastDayOfMonth()); System.out.println(endOfMonth.toString()); //2013-05-31 LocalDate nextTue = date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)); System.out.println(nextTue.toString()); //2013-05-21
5. Fluent API
Creating date objects now can be done using builder pattern also. The builder pattern allows the object be built using individual parts. This is achieved using the methods prefixed by “at”.
//Builder pattern OffsetDateTime offsetDateTime = Year.of(2013) .atMonth(Month.MAY).atDay(15) .atTime(0, 0) .atOffset(ZoneOffset.of("+03:00")); //factory method OffsetDateTime date2 = OffsetDateTime.of(2013, 5, 15, 0, 0, 0, 0, ZoneOffset.of("+03:00"));
6. System Clock
A new class Clock is proposed in the new release. This simulates the system clock functionality.While doing unit testing, you are often required to test an API on future dates. For this, we had been forwarding the system clock for the next date, and then again restarting the server and testing the application.
Now, no need to do this. Use
Clock class to simulate this scenario.
Clock clock = Clock.systemDefaultZone(); System.out.println(clock); //SystemClock[Asia/Calcutta] System.out.println(clock.instant().toString()); //2013-05-15T06:36:33.837Z System.out.println(clock.getZone()); //Asia/Calcutta Clock anotherClock = Clock.system(ZoneId.of("Europe/Tiraspol")); System.out.println(anotherClock); //SystemClock[Europe/Tiraspol] System.out.println(anotherClock.instant().toString()); //2013-05-15T06:36:33.857Z System.out.println(anotherClock.getZone()); //Europe/Tiraspol Clock forwardedClock = Clock.tick(anotherClock, Duration.ofSeconds(600)); System.out.println(forwardedClock.instant().toString()); //2013-05-15T06:30Z
ZoneOffsetclass represents a fixed offset from UTC in seconds. This is normally represented as a string of the format “±hh:mm”.
TimeZoneclass represents the identifier for a region where specified time zone rules are defined.
ZoneRulesare the actual set of rules that define when the zone-offset changes.
8. Format a Date
Date formatting is supported via two classes, mainly i.e. DateTimeFormatterBuilder and DateTimeFormatter. DateTimeFormatterBuilder works on builder pattern to build custom patterns whereas
DateTimeFormatter provides necessary input in doing so.
DateTimeFormatterBuilder formatterBuilder = new DateTimeFormatterBuilder(); formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME).appendLiteral("-").appendZoneOrOffsetId(); DateTimeFormatter formatter = formatterBuilder.toFormatter(); System.out.println(formatter.format(ZonedDateTime.now()));
These are major changes that I was able to identify and work on.
Happy Learning !!