PLATINUM PARTNER GOLD PARTNER GENERLN PARTNER Pasti a

  • Slides: 32
Download presentation
PLATINUM PARTNER GOLD PARTNER GENERÁLNÍ PARTNER Pasti a pastičky při práci s datem a

PLATINUM PARTNER GOLD PARTNER GENERÁLNÍ PARTNER Pasti a pastičky při práci s datem a časem v Javě Petr Adámek petr. adamek@bilysklep. cz

Content § § JSR-310: Date and Time API essential classes Daylight saving time Leap

Content § § JSR-310: Date and Time API essential classes Daylight saving time Leap Seconds Best practices recapitulation

JSR-310: Date and Time API essential classes

JSR-310: Date and Time API essential classes

JSR-310: Date and Time API essential classes § Instant – a point in timeline,

JSR-310: Date and Time API essential classes § Instant – a point in timeline, nanosecond scale § Date / Time without time zone (ISO-8601 calendar system) – Local. Date – a date without a time-zone (e. g. 2017 -11 -14) – Local. Time – a time without a time-zone (e. g. 12: 45: 00. 00001) – Local. Date. Time – a date-time without a time-zone § Date / Time with time zone – Zone. Offset – time-zone offset (e. g. +01: 00) – Zone. Id – id of time-zone (e. g. Europe/Prague) – Offset. Date. Time – a date in time-zone with specific Zone. Offset – Zoned. Date. Time – a date in time-zone with specific Zone. Id

Examples / Quiz § How to store timestamp of some system event? – Instant

Examples / Quiz § How to store timestamp of some system event? – Instant § How to store date of birth? – Local. Date § How to store start and end of working hours? – Local. Time? • What if the shift is over midnight? • What if the shift contains transition from/to daylight saving time? • What if the shift starts within transition period from daylight saving time?

Local. Time § Local. Time represents time within a day § Min value is

Local. Time § Local. Time represents time within a day § Min value is 00: 00, max value is 23: 59. 99999 § If the operation plus or minus overflows or underflows the day, no exception is thrown and day part is just truncated § Due to this is quite tricky to write a for cycle iterating over the whole day with Local. Time (it is difficult to detect end of interval) § Operations with two times in different days (e. g. shift overnight) need special handling

Local Date/Time and daylight saving time § Local. Time / Local. Date. Time have

Local Date/Time and daylight saving time § Local. Time / Local. Date. Time have no information about time-zone, therefore these classes can’t handle timezone related aspects like Daylight saving time § Calculations affected by transition to/from Daylight saving time will be incorrect – Calculated duration of interval containing transition to/from Daylight saving time will be longer/shorter by one hour – Operation plus or minus over transition to/from Daylight saving time will return result which is later/earlier by one hour

Calculations affected by daylight saving time Zone. Id zone. Id = Zone. Id. of("America/Chicago");

Calculations affected by daylight saving time Zone. Id zone. Id = Zone. Id. of("America/Chicago"); // November 5, 2017, is day with transition from CDT to CST Local. Date. Time local. Start = Local. Date. Time. of(2017, Month. NOVEMBER, 5, 0, 0); Local. Date. Time local. End = Local. Date. Time. of(2017, Month. NOVEMBER, 5, 6, 0); Zoned. Date. Time zoned. Start = local. Start. at. Zone(zone. Id); Zoned. Date. Time zoned. End = local. End. at. Zone(zone. Id); System. out. println(local. Start. plus. Hours(6)); // 2017 -11 -05 T 06: 00 System. out. println(zoned. Start. plus. Hours(6). to. Local. Date. Time()); // 2017 -11 -05 T 05: 00 System. out. println(Duration. between(local. Start, local. End)); // PT 6 H System. out. println(Duration. between(zoned. Start, zoned. End)); // PT 7 H

Daylight saving time transitions Date November 5, 2017 (day of change from CDT to

Daylight saving time transitions Date November 5, 2017 (day of change from CDT to CST) Time in UTC 6: 00 6: 59 7: 00 7: 59 8: 00 Time in America/Chicago 1: 00 1: 59 2: 00 Offset in America/Chicago -05: 00 -06: 00 Local times between 1: 00 a 1: 59 are ambiguous (overlap) Date March 11, 2018 (day of change from CST to CDT) Time in UTC 6: 00 6: 59 7: 00 7: 59 8: 00 Time in America/Chicago 0: 00 0: 59 1: 00 1: 59 3: 00 Offset in America/Chicago -6: 00 -06: 00 -05: 00 Local times between 2: 00 a 2: 59 are invalid (gap)

Local. Date. Time at daylight saving time transition § When transforming Local. Date. Time

Local. Date. Time at daylight saving time transition § When transforming Local. Date. Time which is in overlap or gap period, offset before the transition is used – The result is a "best" value, rather than the "correct" value – See Zone. Rules. get. Offset(Local. Date. Time) for more details Zone. Id cst = Zone. Id. of("America/Chicago"); Local. Date. Time overlap = Local. Date. Time. of(2017, Month. NOVEMBER, 5, 1, 30); System. out. println(overlap. at. Zone(cst)); // 2017 -11 -05 T 01: 30 -05: 00[America/Chicago] (offset before transition is -5: 00) Local. Date. Time gap = Local. Date. Time. of(2018, Month. MARCH, 11, 2, 30); System. out. println(gap. at. Zone(cst)); // 2018 -03 -11 T 03: 30 -05: 00[America/Chicago] (offset before transition is -6: 00)

Local. Date. Time at daylight saving time transition § Local. Date. Time and Zone.

Local. Date. Time at daylight saving time transition § Local. Date. Time and Zone. Id are not sufficient for exact representation of time due to ambiguity in overlap – Use combination of Local. Date. Time & Zone. Id & Zone. Offset, or – Use combination of Instant & Zone. Id, or – Use Zoned. Date. Time Instant + Zone. Offset ➡ Local. Date. Time + Zone. Offset ➡ Instant + Zone. Offset ➡ Offset. Date. Time ➡ Instant + Zone. Offset Instant + Zone. Id ➡ Local. Date. Time + Zone. Id ➡ Instant + Zone. Id ➡ Local. Date. Time + Zone. Id + Offset ➡ Instant + Zone. Id ➡ Zoned. Date. Time ➡ Instant + Zone. Id

How to store start and end of working hours? § What if the shift

How to store start and end of working hours? § What if the shift is over midnight? – Store as Local. Time, but define mechanism how to represent shift which is over midnight (e. g. explicit next day flag or end before start implicit flag) § What if the shift contains transition from/to daylight saving time? – Transform to Zoned. Date. Time before performing any calculations § What if the shift starts within transition period from daylight saving time? – Add info about offset or define (and document!) rule for solving ambiguity.

Daylight saving time in different zones § Start and end of daylight saving time

Daylight saving time in different zones § Start and end of daylight saving time could be different for different time-zones § Therefore the offset between two zones could be different during intermediate time period

Zone. Id § Zone. Id – Fixed offsets – a fully resolved offset from

Zone. Id § Zone. Id – Fixed offsets – a fully resolved offset from UTC/Greenwich, that uses the same offset for all local date-times – Geographical regions – an area where a specific set of rules for finding the offset from UTC/Greenwich apply § Use zone identification in form of Continent/City (Europe/Prague) – Zone abbreviations are not standardized, could be subject of localization – Some zone abbreviations are ambiguous – Ambiguity about daylight saving time

Interoperability

Interoperability

Interoperability with legacy classes Date and Time API class Legacy class SQL type java.

Interoperability with legacy classes Date and Time API class Legacy class SQL type java. time. Instant java. util. Date none java. time. Local. Date java. sql. Date DATE java. time. Local. Time java. sql. Time TIME java. time. Local. Date. Time java. sql. Timestamp TIMESTAMP § Conversion between java. sql. Date/java. sql. Timestamp and Local. Date/Local. Time operates with default time zone. § Make sure that the time is processed with correct time-zone

JDBC interoperability § Support for new Date and Time API (JSR-310) classes has been

JDBC interoperability § Support for new Date and Time API (JSR-310) classes has been introduced in JDBC 4. 2 (see the table below) § New types are supported via Result. Set. get. Object(…) or Prepared. Statement. set. Object(. . . ) methods § For JDBC drivers which don’t support JDBC 4. 2 yet, we have to use java. sql. Date, java. sql. Time and java. sql. Timestamp classes.

JPA and Hibernate § Support for new Date and Time API (JSR-310) classes has

JPA and Hibernate § Support for new Date and Time API (JSR-310) classes has been introduced in JPA 2. 2 (see the table below) § Support in Hibernate is possible even for JPA 2. 1 with org. hibernate: hibernate-java 8 module (supports also Instant and Zoned. Date. Time) JAVA TYPE JDBC TYPE java. time. Local. Date DATE java. time. Local. Time TIME java. time. Local. Date. Time TIMESTAMP java. time. Offset. Time TIME_WITH_TIMEZONE java. time. Offset. Date. Time TIMESTAMP_WITH_TIMEZONE java. time. Zoned. Date. Time not supported

Leap Second

Leap Second

Leap Second § Earth's rate of rotation is irregular § Mean solar day is

Leap Second § Earth's rate of rotation is irregular § Mean solar day is slightly longer (by roughly 0. 001 seconds) than 24 hours now § UT 1 is the principal form of Universal Time § UTC is an atomic timescale that approximates UT 1. § UTC is kept within 0. 9 seconds of UT 1 by the introduction of occasional intercalary leap seconds. § 27 seconds inserted since 1972, current difference between UTC and TAI (International Atomic Time) is 37 seconds

Inserting of Leap Second § Leap second insertion is not regular, it is scheduled

Inserting of Leap Second § Leap second insertion is not regular, it is scheduled by International Earth Rotation and Reference Systems Service (IERS) § Leap second is usually inserted at the end of June 30 or December 31 (UTC standard allows leap seconds to be applied at the end of any UTC month) § Leap second is inserted after 23: 59 UTC (as 23: 59: 60), so the last minute (called leap minute) has 61 seconds. § Leap second may be also removed (last minute has only 59 seconds), but it never happen yet.

Leap second in Systems § Systems usually don’t support minute with 61 seconds, the

Leap second in Systems § Systems usually don’t support minute with 61 seconds, the day has always 86 400 seconds § When the leap second is inserted, current time a) is just moved by one second back (e. g. in POSIX UNIX), or b) is slowed down (e. g. by 0. 1 % last 1000 seconds in UTC-SLS), or c) is stopped. Current Time in a day with Leap Second Day length UTC 23: 43: 22. 000 23: 59. 999 23: 59: 60. 000 23: 59: 60. 999 00: 00. 000 86 401 s a) 23: 43: 22. 000 23: 59. 999 00: 00. 000 00: 00. 999 00: 00. 000 86 400 s b) 23: 43: 21. 999 23: 59. 000 23: 59. 001 23: 59. 999 00: 00. 000 86 400 s c) 23: 43: 22. 000 23: 59. 999 00: 00: 00. 000 86 400 s

Leap second in Java § Java Time Scale (used by Date and Time API)

Leap second in Java § Java Time Scale (used by Date and Time API) divides each calendar day into exactly 86 400 seconds § Java Time Scale is identical to UTC-SLS for dates/times since November 3, 1972 § However Clock implementations are not required to actually perform the UTC-SLS slew! § Default Clock implementation is based on System. current. Time. Millis(), which fully relies on underlying operating system.

Leap second in Java – Consequences § Current time (Clock or System. current. Time.

Leap second in Java – Consequences § Current time (Clock or System. current. Time. Millis()) need not be monotonic (see later) § One second need not correspond to SI second § System. current. Time. Millis() and Instant. get. Epoch. Second() differs from exact real value (by 27 seconds) § Leap seconds are ignored when calculating duration or performing other date/time arithmetic § If you need to handle leap seconds properly (e. g. for scientific applications), use e. g. Time 4 J

Current time handling

Current time handling

Monotonicity § Natural time is monotonic (it is go only forward) § Current time

Monotonicity § Natural time is monotonic (it is go only forward) § Current time in java need not be monotonic – Due leap second (for non UTC-SLS clock) – Due NTP adjustment – Due system time change – Due slightly different time on different cluster nodes

Getting current time § Don’t use System. current. Time. Millis(), or Any. Date. Time.

Getting current time § Don’t use System. current. Time. Millis(), or Any. Date. Time. Type. now() (e. g. Instant. now()) without explicit Clock for getting current time in your components § Always use a Clock which is injected to your component as a source of current time (see example on next slide) – Allows to write deterministic unit tests (by using Clock. fixed. Clock(Instant, Zone. Id)) – Allows to implement time shift functionality (useful for testing environment) – Custom clock implementation could by used (e. g. more accurate, monotonic or based on specific time source)

Component working with current time public class My. Component. Impl { private final Clock

Component working with current time public class My. Component. Impl { private final Clock clock; public My. Component. Impl(Clock clock) { this. clock = clock; } public void method. Which. Works. With. Current. Time() { Instant now = Instant. now(clock); //. . . } }

Accurate duration measuring § Don’t use System. current. Time. Millis(), Clock or Instant. now()

Accurate duration measuring § Don’t use System. current. Time. Millis(), Clock or Instant. now() for duration measuring – Granularity depends on underlying operating system, could be more than one millisecond – No guarantee about accuracy – System time may be changed or adjusted unexpectedly (e. g. due leap second, NTP adjustment or system time change) § Use System. nano. Time() for duration measuring – Higher resolution and accuracy – Independent on unexpected system time change

Recapitulation

Recapitulation

Best practices recapitulation § Don’t use Local. Date/Local. Time/Local. Date. Time for storing, exchanging

Best practices recapitulation § Don’t use Local. Date/Local. Time/Local. Date. Time for storing, exchanging or performing calculations with data which could be Time Zone sensitive. § Don’t depend on monotonicity of current time § Always use Clock for fetching current time § Don’t try to store Zoned. Date time to TIMESTAMP column, store the time-zone separately in case of need.

Děkuji za pozornost. www. Java. Days. cz www. gopas. cz

Děkuji za pozornost. www. Java. Days. cz www. gopas. cz