Time Sucks

A grumpy lightning talk
by Ryan Skonnord

Why does time suck?

  1. Never have enough of it
  2. Requires management skills
  3. Eventually kills you

But most of all...

It causes bugs!

The Internet offers a two-part list of 113 ways that time screws up software.

There are many contenders for the biggest cause of time-related bugs...

  • time zones
  • Daylight Saving Time
  • clock synchronization

but today I'll be focusing on my personal pet peeve...

false precision.

A joke!

What not to do

(a.k.a., what we do)

Input "2016-03-04"
Stored as 2016-03-04 00:00:00 PST
Equivalent to 2016-03-04 08:00:00 UTC

The culprit

The year 1996 and the Date class.

An annoyingly one-size-fits-all approach to storing and representing time values, riddled with early-OOP antipatterns.

Other problems with Date

  • It's mutable
    • In case noon spontaneously mutates into 2:30
  • Magic numbers instead of enums
  • It doesn't contain time zone information but its toString pretends it does
  • Do I want java.util.Date, java.util.Calendar, or java.sql.Date?

The solution

Joda-Time!

Or, as it is known in Java 8, the java.time.* package.

What is Joda-Time?

A library of improved classes for representing time.

Java, pre-8 Few classes Overloaded and complex
Joda-Time Larger and more complex selection of classes Each class is simple

The remainder of the talk will be a brief tour of Joda-Time's basic classes.

If you are not a Java coder, I hope it will provide a good philosophical example.

Instant

  • Represents an instantaneous point in the universal time line
  • Independent of time zones and locale
  • Equivalent to a number of seconds after the Unix epoch

Example:
Neil Armstrong first stepped onto the Moon at
July 21, 1969, 02:56 UTC.

LocalDate

  • Represents a date on the ISO-8601 (Gregorian) calendar
  • Independent of time zones and locale
  • A time zone is needed to introduce time-of-day details (e.g., at what Instant did the day begin)

Example:
The release date of the movie Primer was
October 8, 2004.

LocalTime

  • Represents a time of day ("as seen on a wall clock")
  • Belongs to no particular day
  • Independent of time zones and locale

Example:
WiFri begins at
4:30 PM.

MonthDay

  • Represents a date on the ISO-8601 (Gregorian) calendar during no particular year
  • Independent of time zones and locale

Example:
Bastille Day is celebrated on
July 14.

LocalDateTime

  • Represents a time of a particular day
  • Independent of time zones and locale
  • LocalDateTime + time zone = Instant

Example:
The next Game of Thrones season premiere episode will air
April 24, 2016 at 9:00 PM.

Times in places

ZonedDateTime and OffsetDateTime represent date-and-timestamps in particular time zones.

Both can be translated into Instant objects.

Time zone versus offset?

An offest is just a number of hours offset from UTC.

A time zone defines an offset, with complicated baggage about stuff like Daylight Saving Time.

Example:
The Pacific Time Zone's offset is equal to UTC minus eight hours in the winter and UTC minus seven hours in the summer.

Duration

  • Represents an amount of time, as measured on a clock
  • Represents no particular start or end time, only the length
  • Independent of time zones and locale

Example:
Regulation time in a game of soccer is
90 minutes.

Period

  • Represents an interval between calendar dates
  • Represents no particular start or end dates, only the length
  • Independent of time zones and locale

Example:
A warranty lasts for
90 days.

Why two classes for Duration and Period?

To avoid false precision!

Days, as measured on a calendar, don't neatly translate into 24-hour intervals.

What if Daylight Saving Time begins or ends during the period? What if you travel between time zones?

Representing a 90-day warranty as 2,160 hours is silly.

Time units

The java.time.temporal.* package provides nice enums for every time unit and calendar field you can think of.

Fear magic numbers no longer.

Other calendars

But I thought the whole point of the Calendar class was to avoid ethnocentric preference for the Gregorian calendar?

It's not Gregorian; it's ISO-8601.

Can't be ethnocentric with "International" right in the name.

The java.time.chrono.* package has got you covered with library classes for Islamic, Japanese, Chinese, and Thai calendars.

Time left for questions?