Created
June 7, 2019 11:59
-
-
Save l0co/870786bf6fea0e64a8a60606ea850f25 to your computer and use it in GitHub Desktop.
Cheatsheet of using Java 8 date time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Here is the jdk8 datetime cheatsheet and explanation why we use ZonedDateTime and Instant in TimeService. | |
*/ | |
// this is the 01.03.2016 00:00 in server timezone (Europe/Warsaw) == EXACTLY THE SAME AS THE SYSTEM TIME | |
ZonedDateTime zonedDateTime = ZonedDateTime.of(2016, 3, 1, 0, 0, 0, 0, ZoneId.systemDefault()); | |
System.out.println(zonedDateTime); // 2016-03-01T00:00+01:00[Europe/Warsaw] | |
// this is the same 01.03.2016 00:00 but doesn't carry timezone information | |
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime(); | |
System.out.println(localDateTime); // 2016-03-01T00:00 | |
// the important info about ZonedDateTime and LocalDateTime - they are exactly the same after conversion, just LocalDateTime | |
// doesn't carry timezone part; no time part recalculation is done on such conversion | |
System.out.println(localDateTime.atZone(ZoneId.systemDefault())); // back to 2016-03-01T00:00+01:00[Europe/Warsaw] | |
/* | |
Should application use LocalDateTime or ZonedDateTime? | |
Short answer: ZonedDateTime. | |
Long answer: | |
For internal calculations both can be used, having in mind that: | |
- LocalDateTime shouldn't ever be passed outside the service, for example to the browser or to other service possibly | |
working in different time zone. Browser will consider this is UTC time or browser timezone time (depending on parser | |
implementation) while the other service will consider it a timestamp in its timezone. If the timezone of browser or | |
other service will be different than timezone of your service, the timestamp information will be broken. | |
- LocalDateTime shouldn't ever be saved to database, because it will be considered a timestamp with UTC timezone, what | |
is not true. | |
For both above usages you should use ZonedDateTime, so the cheat answer for "should application use LocalDateTime or | |
ZonedDateTime?" question is: use ZonedDateTime and it will be safer. | |
*/ | |
// instant also doesn't carry timezone information but IT DIFFERS from LocalDateTime because it is considered to be in UTC | |
Instant instant = Instant.from(zonedDateTime); | |
System.out.println(instant); // 2016-02-29T23:00:00Z (!!!) | |
// the important info about ZonedDateTime and Instant - they will have different time parts after conversion | |
// for example for Europe/Warsaw timezone Instant will be an hour back from the ZonedDateTime | |
System.out.println(instant.atZone(ZoneId.systemDefault())); // 2016-03-01T00:00+01:00[Europe/Warsaw] | |
// instant can't be obtained from LocalDateTime because LocalDateTime without timezone has unknown time | |
try { | |
instant = Instant.from(localDateTime); | |
} catch (DateTimeException e) { | |
System.out.println(String.format("%s: %s", e.getClass().getSimpleName(), e.getMessage())); // DateTimeException: Unable to obtain Instant from TemporalAccessor: 2016-03-01T00:00 of type java.time.LocalDateTime | |
} | |
/* | |
Should application use Instant or ZonedDateTime? | |
Short answer: both. | |
Long answer: | |
Instant and ZonedDateTime can be used interchangeably, because you can always recover one from another. Instant is just without | |
timezone but always in UTC, while ZonedDateTime is always with timezone. | |
Hibernate/mongo driver will recognize both fields - Instant will be considered UTF while ZonedDateTime will be recogniez as | |
timestamp with timezone. Mongo driver anyway stores everything in UTC (so ZonedDateTime will be recalculated to UTC), please | |
refer to {@code AuditableDocument} for the example. Hibernate will do the same, however we should store all timestamps with | |
timezone, while default JPA {@code @Temporal} declaration doesn't have the timezone. This is why we need additional annotation | |
{@code @Column(columnDefinition = POSTGRES_TIMEZONE_TIMESTAMP)} on timestamp entity fields. Please refer to | |
{@code AuditableEntity} for the example. | |
Regarding Jackson, both Instant and ZonedDateTime returned to the browser will be well interpreted by the JavaScript. Please | |
check examples in {@code TimeController} from {@code ax} service. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment