A big part of developer community has been complaining about Date and Calender classes. Reasons were many such as hard to understand, hard to use and not flexible. Date class has even become obsolete and java docs suggest to use Calender class instead of Date class. And on top of all, Date comparison is buggy and I have also faced such issue in past.
Moving forward, JAVA 8 (Lambda) is expected to release the new Date and Time APIs/classes (JSR-310), also called as ThreeTen, which will simply change the way you have been doing till date. 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 key public classes are immutable and thread-safe
- Defined terminology and behavior that other areas in computing can adopt
Section in this post:
New classes to represent local date and timezone
New classes to represent timestamp and duration
Added utility classes over existing enums
Date adjusters introduced
Building dates will be easier
New class to simulate system/machine clock
Timezone handling related changes
Date formatting changes
References
New classes to represent local date and timezone
The new classes intended to replace Date class are LocalDate, LocalTime and LocalDateTime.LocalDate: The LocalDate class represents a date. There is no representation of a time or time-zone.
1
2
3
4
5
6
7
|
LocalDate
localDate = LocalDate.now(); System.out.println(localDate.toString());
//2013-05-15 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 System.out.println(localDate.plusDays(12).toString());
//2013-05-27 |
1
2
3
4
5
6
7
8
|
//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 |
1
2
3
4
5
|
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
2
3
4
5
6
7
8
9
10
11
12
|
OffsetDateTime
offsetDateTime = OffsetDateTime.now(); System.out.println(offsetDateTime.toString());
//2013-05-15T10:10:37.257+05:30 offsetDateTime
= OffsetDateTime.now(ZoneId.of("+05:30")); System.out.println(offsetDateTime.toString());
//2013-05-15T10:10:37.258+05:30 offsetDateTime
= OffsetDateTime.now(ZoneId.of("-06:30")); System.out.println(offsetDateTime.toString());
//2013-05-14T22:10:37.258-06:30 ZonedDateTime
zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Paris")); System.out.println(zonedDateTime.toString());
//2013-05-15T06:45:45.290+02:00[Europe/Paris] |
New classes to represent timestamp and duration
For representing the specific timestamp ant any moment, the class needs to be used is Instant. The Instant class represents an instant in time to an accuracy of nanoseconds. Operations on an Instant include comparison to another Instant and adding or subtracting a duration.
1
2
3
4
5
|
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 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Duration
duration = Duration.ofMillis(5000); System.out.println(duration.toString());
//PT5S duration
= Duration.ofSeconds(60); System.out.println(duration.toString());
//PT1M duration
= Duration.ofMinutes(10); System.out.println(duration.toString());
//PT10M duration
= Duration.ofHours(2); System.out.println(duration.toString());
//PT2H duration
= Duration.between(Instant.now(),
Instant.now().plus(Duration.ofMinutes(10))); System.out.println(duration.toString());
//PT10M |
1
2
3
4
5
6
7
8
9
|
Period
period = Period.ofDays(6); System.out.println(period.toString());
//P6D period =
Period.ofMonths(6); System.out.println(period.toString());
//P6M period =
Period.between(LocalDate.now(), LocalDate.now().plusDays(60)); System.out.println(period.toString());
//P1M29D |
Added utility classes over existing 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 which work on top of these enums. I am taking an example such a class DayOfWeek. This class is a wrapper of day enums and can be used consistently with other classes also.
1
2
3
4
5
6
7
8
|
//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 ? |
Date adjusters introduced
Date adjusters are another beautiful and useful addition in 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?Lets see in code.
1
2
3
4
5
6
7
|
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 |
Building dates will be easier
Making date objects now can be done using builder pattern also. The builder pattern allows the object you want to be built up using individual parts. This is achieved using the methods prefixed by “at”.
1
2
3
4
5
6
7
8
9
10
11
|
//Builder
pattern used to make date object OffsetDateTime
date1 = Year.of(2013) .atMonth(Month.MAY).atDay(15) .atTime(0,
0) .atOffset(ZoneOffset.of("+03:00")); System.out.println(date1);
//2013-05-15T00:00+03:00 //factory
method used to make date object OffsetDateTime
date2 = OffsetDateTime. of(2013,
5, 15, 0, 0, 0, 0, ZoneOffset.of("+03:00")); System.out.println(date2);
//2013-05-15T00:00+03:00 |
New class to simulate system/machine clock
A new class Clock is proposed in new release. This simulates the system clock functionality. I loved this feature most of all others. The reason is while doing unit testing. you are often required to test a API in future date. For this we had been forwarding the system clock for next date, and then again restart the server and test the application.Now, no need to do this. Use Clock class to simulate this scenario.
1
2
3
4
5
6
7
8
9
10
11
12
|
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 |
Timezone handling related changes
Timezone related handling is done by 3 major classes. These are ZoneOffset, TimeZone, ZoneRules.- The ZoneOffset class represents a fixed offset from UTC in seconds. This is normally represented as a string of the format “±hh:mm”.
- The TimeZone class represents the identifier for a region where specified time zone rules are defined.
- The ZoneRules are the actual set of rules that define when the zone-offset changes.
1
2
3
|
//Zone
rules System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isDaylightSavings(Instant.now())); System.out.println(ZoneRules.of(ZoneOffset.of("+02:00")).isFixedOffset()); |
Date formatting changes
Date formatting is supported via two classes mainly i.e. DateTimeFormatterBuilder and DateTimeFormatter. DateTimeFormatterBuilder works on builder pattern to build custom patterns where as DateTimeFormatter provides necessary input in doing so.
1
2
3
4
5
6
|
DateTimeFormatterBuilder
formatterBuilder = new DateTimeFormatterBuilder(); formatterBuilder.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME) .appendLiteral("-") .appendZoneOrOffsetId(); DateTimeFormatter
formatter = formatterBuilder.toFormatter(); System.out.println(formatter.format(ZonedDateTime.now())); |
References
- https://jdk8.java.net/lambda/
- http://sourceforge.net/apps/mediawiki/threeten/index.php?title=User_Guide
Please remember that Lambda release is in progress, So some of above listed features
might get disappear in future releases.
0 comments:
Post a Comment