java.time — Date-time programming made easy

java.time — Date-time programming made easy

Date-time work is tricky stuff, often surprising and counter-intuitive. Issues like time zones, offsets, UTC/GMT, Daylight Saving Time (DST), epoch, Leap Year, Leap Second, and historical anomalies create confusing complications.

Fortunately we have a powerful new open-source tool: the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) framework built into Java 8 and later, and back-ported to Java 6 & 7 & Android.

We walk through the key concepts of date-time in business-oriented apps. We see those concepts in action as we tour the classes offered by java.time. Practical code examples show how to adjust between time zones, how to parse and generate strings in various formats including localization, how to get date-times in/out of databases, and how to represent a span of time. Learn the difference between time zone and locale. Understand the meaning of a “local” versus a “zoned” date-time. Get tips on how to change your thinking and your coding habits to make handling date-time much easier, more predictable, and even enjoyable.

Df06000516b540a9d7d58309f9ad1a18?s=128

Basil Bourque

February 02, 2018
Tweet

Transcript

  1. java.time Date-time programming made easy concepts & practice using open-source


    java.time framework Basil Bourque basil.bourque@POBox.com 2016-02-18 1
  2. Time keeps on 
 slipping, slipping, slipping… Into the future

    “Fly Like an Eagle” The Steve Miller Band 2
  3. © 2016 Basil Bourque Timeline Count Epoch Now Past Future

    + - 3
  4. © 2016 Basil Bourque Epochs January 0, 1 BC January

    1, 1 AD January 1, 1601 December 31, 1840 November 17, 1858 December 30, 1899 December 31, 1899 January 0, 1900 January 1, 1900 January 1, 1904 December 31, 1967 January 1, 1970 January 1, 1980 January 6, 1980 January 1, 2000 January 1, 2001 4
  5. © 2016 Basil Bourque Epoch - Unix Time January 0,

    1 BC January 1, 1 AD January 1, 1601 December 31, 1840 November 17, 1858 December 30, 1899 December 31, 1899 January 0, 1900 January 1, 1900 January 1, 1904 December 31, 1967 January 1, 1970 January 1, 1980 January 6, 1980 January 1, 2000 January 1, 2001 5
  6. © 2016 Basil Bourque Count of What? POSIX Time (Unix)

    java.util.Date/.Calendar Joda-Time `java.time.Clock` impl. Java 8 Postgres 9 java.sql.Timestamp java.time second 0 millisecond 0.123 millisecond 0.123 millisecond 0.123 microsecond 0.123456 nanosecond 0.123456789 nanosecond 0.123456789 6
  7. © 2016 Basil Bourque Java Libraries java.time Java 8 +

    JSR 310 ThreeTen- Extra java.util.Date java.util.Calendar java.text.SimpleDateFormat Avoid! convert Joda-Time Noda-Time extends defines built-in inspired port .Net 7 IBM > Taligent > Java ThreeTen- Backport Java 6&7 ThreeTen- ABP Android
  8. © 2016 Basil Bourque Offset 8

  9. © 2016 Basil Bourque UTC Coordinated Universal Time UTC (

    not CUT nor TUC ) Z = Zulu ( NATO A…Z, ∼J ) UTC = GMT ( in practice ) All offsets based on UTC Constant:
 ZoneOffset.UTC 9
  10. © 2016 Basil Bourque Instant Moment on the timeline in

    UTC Instant instant = Instant.now() ; Static methods, not constructors. Building block for java.time Gateway for conversion from old classes Instant instant = myJavaUtilDate.toInstant() ; Nanosecond (billions, 9 decimal places) 10
  11. © 2016 Basil Bourque Instant Think Global, Present Local Best

    Practice: Work in UTC business logic data storage database data exchange/ serialization 2016-01-23T12:34:56.789Z Z = Zulu = UTC Often used in your code Any “when” member should be of type `Instant` Formatter is limited `toString` 0, 3, 6, 9
 decimals Think in
 24-hour 
 clock 11
  12. © 2016 Basil Bourque Wall-Clock Time Technical term Defined by

    offset-from-UTC Same moment on time line: 2016-01-23T12:34:56.789Z 2016-01-23T04:34:56.789-08:00 2016-01-23T18:04:56.789+05:30 12
  13. © 2016 Basil Bourque Offset-from-UTC Number of hours & minutes

    Seattle: -08:00 | Québec: -05:00 | India: +05:30 Practical: -12:00 +14:00
 Technical: -18:00 +18:00 Not a formula in algebra: 2016-01-23T04:34:56.789-08:00 + is ahead of UTC
 - is behind UTC Flip the sign to calculate UTC value Tip: Stick with padded zero: +05:30 not +5:30
 Allowed: ±hh:mm ±hhmm ±hh 13
  14. © 2016 Basil Bourque `ZoneOffset` class ZoneOffset offset = 


    ZoneOffset.ofHoursMinutes( 5 , 30 ); ZoneOffset offset = 
 ZoneOffset.ofHoursMinutes( -8 , 0); 14
  15. © 2016 Basil Bourque `OffsetDateTime` class ZoneOffset offset = 


    ZoneOffset.ofHoursMinutes( 5 , 30 ); Instant now = Instant.now();
 OffsetDateTime odt = 
 OffsetDateTime.ofInstant( now , offset ); 2016-01-23T12:34:56.789Z
 2016-01-23T18:04:56.789+05:30 = Instant + ZoneOffset 15
  16. © 2016 Basil Bourque Time Zone Time Zone = (

    Offset-from-UTC + Anomalies ) Rules of adjustment to handle anomalies Daylight Saving Time (DST) Historical transitions, wars & occupation, experiments Bored politicians Rules for past, present, and near future. 16
  17. © 2016 Basil Bourque Time Zone Names Never use 3-4

    letter codes ( EST EDT PDT MST IST ) Not Standardized Not Unique ( IST = India Standard Time, Irish… ) Further confuse DST Use format of continent/region in ASCII English Ex: America/Los_Angeles Europe/Paris India/Kolkata list https:/ /en.wikipedia.org/wiki/ List_of_tz_database_time_zones 17
  18. © 2016 Basil Bourque ‘tz’ Database Formerly: Olson database Changes

    frequently Where? Host operating system JVM implementation Joda-Time library (from source code) Manual updates to JVM now easier: TZUpdater tool 18
  19. © 2016 Basil Bourque `ZoneId’ class ZoneId.of( “America/Montreal” ); Superclass

    of ‘ZoneOffset’ 19
  20. © 2016 Basil Bourque ZonedDateTime ZonedDateTime = Instant + ZoneId

    ZoneId zMontreal = ZoneId.of( “America/Montreal” );
 ZoneId zKolkata = ZoneId.of( “Asia/Kolkata” );
 
 Instant now = Instant.now();
 
 ZonedDateTime zdtMontreal = 
 ZonedDateTime.ofInstant( now , zMontreal );
 
 ZonedDateTime zdtKolkata = 
 ZonedDateTime.ofInstant( now , zKolkata ); 2016-01-23T04:34:56.789-08:00[America/Los_Angeles] 20
  21. © 2016 Basil Bourque Changing time zones ZonedDateTime::withZoneSameInstant ZonedDateTime zdtMontreal

    = 
 zdtKolkata.withZoneSameInstant( zoneIdMontreal ); 21
  22. © 2016 Basil Bourque On Timeline Instant OffsetDateTime ZonedDateTime 22

  23. © 2016 Basil Bourque Off Timeline LocalDateTime LocalTime LocalDate 23

  24. © 2016 Basil Bourque “Local…” Just an idea about a

    *possible* moment on the timeline, but *not* actually a moment. No real meaning.
 To get a real moment, adjust into a time zone. Christmas this year: 2016-12-25T00:00:00.0 All AcmeCorp factories take lunch Noon–13:00 Epoch Dehli Past Future Detroit Düsseldorf Now 24
  25. © 2016 Basil Bourque LocalDate class Date-only, without time-of-day, without

    time zone No time zone stored, yet crucial to determine “today” New day dawns earlier in the east LocalDate today = 
 LocalDate.now( ZoneId.of( “America/Montreal” ) ); May be used in business. ZonedDateTime may be better. Contract signed, warranty expires, employee hired. 25
  26. © 2016 Basil Bourque “Local…” usages Use LocalDate, LocalTime, and

    LocalDateTime for parsing text with no explicit time zone or offset String input = “2016-01-23T04:34:56.789”; 
 LocalDateTime ldt = LocalDateTime.parse( input );
 // Assume Seattle-time was intended.
 ZoneId zoneId = ZoneId.of( “America/Los_Angeles” );
 ZonedDateTime zdt = ldt.atZone( zoneId ); First moment of the day. ZonedDateTime.now( zoneId )
 .toLocalDate().atStartOfDay( zoneId ); 26
  27. © 2016 Basil Bourque java.time package 27

  28. © 2016 Basil Bourque API Re-Org Foundation Instant ZonedDateTime ZoneId

    ZoneOffset (.UTC) Offset-from-UTC OffsetDateTime OffsetTime Off Timeline LocalDate LocalTime LocalDateTime Span of Time Duration Period Testing Clock Handy MonthDay Year YearMonth DayOfWeek Month 28
  29. © 2016 Basil Bourque ThreeTen-Extra Extends java.time Independent of Oracle

    & JSR 310 By the same people, the makers of java.time/Joda-Time Double Goals (contradictory?) Made to be useful in production A proving ground for possible inclusion in java.time 29
  30. © 2016 Basil Bourque java.time + ThreeTen-Extra Foundation Instant ZonedDateTime

    ZoneId ZoneOffset Offset-from-UTC OffsetDateTime OffsetTime Off Timeline LocalDate LocalTime LocalDateTime Span of Time Duration Period Testing Clock Handy MonthDay Year YearMonth DayOfWeek Month Interval DayOfMonth DayOfYear AmPm YearQuarter Quarter Days, Weeks, Months, Years (… weekend adjusters …) 30
  31. © 2016 Basil Bourque ISO 8601 Standard of textual representations

    of date-time values Surprisingly practical and sensible. Unambiguous. See the Wikipedia page. Used by default for parsing/generating strings. Extended by java.time. Appends [name of time zone].
 2016-01-23T04:34:56.789-08:00[America/Los_Angeles] String != date-time. USD $ 213.07 31
  32. © 2016 Basil Bourque ISO 8601 2016-02-16T23:30:58.123+00:00
 2016-02-16T23:30:58,123Z
 20160216T233058Z “basic”

    format 2016-02-16
 2016-047 ordinal date YYYY-MM but not YYYYMM hh:mm:ss.sss hhmmss.sss
 hh:mm:ss hhmmss
 hh:mm hhmm hh 32
  33. © 2016 Basil Bourque ISO 8601 Duration Number of years,

    months, days, hours, minutes, seconds Not on the timeline PnYnMnDTnHnMnS P<date>T<time>
 PT5M
 P3Y6M4DT12H30M5S PT36H versus P1DT12H <start>/<end> Add R for repeating 33
  34. © 2016 Basil Bourque java.time Duration java.time breaks this into

    two pieces Period = years, months, days Duration = hours, minutes, seconds Period p = 
 Period.between( localDate , localDate ); Duration d = 
 Duration.between( zdtStart , zdtStop ); Parse/generate strings in ISO 8601 duration format. 34
  35. © 2016 Basil Bourque Interval In the ThreeTen-Extra project. Interval

    interval = 
 Interval.of( instantStart , instantStop );
 // Pass: zdt.toInstant() contains( instant ) abuts( interval )
 encloses( interval )
 overlaps( interval ) ISO 8601 2007-12-03T10:15:30Z/2007-12-04T10:15:30Z 35
  36. © 2016 Basil Bourque ISO 8601 Week-Based Year Different definitions

    Old java.util.Calendar definition varies by Locale ISO 8601 definition 52 or 53 weeks Week # 1 holds the first Thursday Week runs Monday-Sunday 2016-W06 2016W06
 2016-W06-7 2016W067 36
  37. © 2016 Basil Bourque TemporalAdjuster 37

  38. © 2016 Basil Bourque Immutable Objects Design pattern No “setter”

    methods to change/“mutate” attributes with() from() to() of() Automatically thread-safe (!) Factory methods, not constructors Good for value objects simple class, no life span in business logic 38