26
This thing all things devours; Birds, beasts, trees, flowers; Gnaws iron, bites steel; Grinds hard stones to meal; Slays king*, ruins town, And beats mountain down. J.R.R. Tolkien * and software developer alike

Java Time Puzzlers

Embed Size (px)

DESCRIPTION

SeaJUG talk with a few puzzles around Joda Time, java.time, and timestamps in general.

Citation preview

Page 1: Java Time Puzzlers

This thing all things devours;Birds, beasts, trees, flowers;Gnaws iron, bites steel;Grinds hard stones to meal;Slays king*, ruins town,And beats mountain down.

J.R.R. Tolkien

* and software developer alike

Page 2: Java Time Puzzlers

a. sunriseb. sunsetc. could be eitherd. that's no sun!

2010-08-03T03:30Z

Page 3: Java Time Puzzlers

a. sunriseb. sunsetc. could be eitherd. that's no sun!

2010-08-03T03:30Z

Page 4: Java Time Puzzlers

a. resolve using nearest cityb. resolve using tz_world shapefilec. resolve with Google Maps APId. store the time zone offset

2010-08-03T03:30Z 49.788, -122.987

Page 5: Java Time Puzzlers

a. resolve using nearest cityb. resolve using tz_world shapefilec. resolve with Google Maps APId. store the time zone offset

2010-08-03T03:30Z 49.788, -122.987

Page 6: Java Time Puzzlers

a. resolve using nearest cityb. resolve using tz_world shapefilec. resolve with Google Maps APId. store the time zone offset

2010-08-03T03:30Z 49.788, -122.987

Page 7: Java Time Puzzlers

a. resolve using nearest cityb. resolve using tz_world shapefilec. resolve with Google Maps APId. store the time zone offset

2010-08-03T03:30Z 49.788, -122.987

Page 8: Java Time Puzzlers

import org.joda.time.DateTime;

DateTime time = new DateTime("2010-08-02T20:30:00-07:00");

assertEquals(20, time.getHourOfDay());

a. passesb. failsc. throws an exceptiond. it depends

Page 9: Java Time Puzzlers

import org.joda.time.DateTime;

DateTime time = new DateTime("2010-08-02T20:30:00-07:00");

assertEquals(20, time.getHourOfDay());

a. passesb. failsc. throws an exceptiond. it depends

Page 10: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

DateTimeZone zone = DateTimeZone.forOffsetHours(-7); DateTime time = new DateTime("2010-08-02T20:30:00-07:00", zone);

assertEquals(20, time.getHourOfDay());

Solution #1Pass an explicit zone to the constructor.

Page 11: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.format.DateTimeFormatter;

import org.joda.time.format.ISODateTimeFormat;

DateTimeFormatter fmt = ISODateTimeFormat

.dateTimeNoMillis().withOffsetParsed(); DateTime time = DateTime.parse("2010-08-02T20:30:00-07:00", fmt);

assertEquals(20, time.getHourOfDay());

Solution #2Use a custom formatter.

Page 12: Java Time Puzzlers

import java.time.OffsetDateTime;

OffsetDateTime time =

OffsetDateTime.parse("2010-08-02T20:30:00-07:00");

assertEquals(20, time.getHourOfDay());

Solution #3Use java.time.OffsetDateTime

Page 13: Java Time Puzzlers

9 hours

a. 5amb. 6amc. too early!d. it depends

When did I get up?

2014-03-08T20:00-08:00

Page 14: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.Duration;

DateTimeZone zone = DateTimeZone.forOffsetHours(-8); DateTime time = new DateTime("2014-03-08T20:00:00", zone);

Duration d = Duration.standardHours(9);

assertEquals(6, time.plus(d).getHourOfDay());

a. passesb. failsc. throws an exceptiond. it depends

Page 15: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.Duration;

DateTimeZone zone = DateTimeZone.forOffsetHours(-8); DateTime time = new DateTime("2014-03-08T20:00:00", zone);

Duration d = Duration.standardHours(9);

assertEquals(6, time.plus(d).getHourOfDay());

a. passesb. failsc. throws an exceptiond. it depends

Page 16: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.Duration;

DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles"); DateTime time = new DateTime("2014-03-08T20:00:00", zone);

Duration d = Duration.standardHours(9);

assertEquals(6, time.plus(d).getHourOfDay());

Don't do math without time zone IDs!

Page 17: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.Duration;

import org.joda.time.Period;

DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles"); DateTime time = new DateTime("2014-03-08T20:00:00", zone);

Duration d = Duration.standardDays(1); Period p = Period.days(1);

assertEquals(time.plus(d), time.plus(p));

a. passesb. failsc. throws an exceptiond. it depends

Page 18: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.DateTimeZone;

import org.joda.time.Duration;

import org.joda.time.Period;

DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles"); DateTime time = new DateTime("2014-03-08T20:00:00", zone);

Duration d = Duration.standardDays(1); Period p = Period.days(1);

assertEquals(time.plus(d), time.plus(p));

a. passesb. failsc. throws an exceptiond. it depends

Page 19: Java Time Puzzlers

import java.time.DateTime;

import java.time.DateTimeZone;

import java.time.Duration;

import java.time.Period;

ZonedDateTime time = ZonedDateTime

.parse("2014-03-08T20:00:00-08:00[America/Los_Angeles]"); Duration d = Duration.ofDays(1); Period p = Period.ofDays(1);

assertEquals(time.plus(d), time.plus(p));

a. passesb. failsc. throws an exceptiond. it depends

Page 20: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.Duration;

DateTime begin = new DateTime();

// watch me run 100 m

DateTime end = new DateTime();

Duration d = new Duration(begin, end);

assertFalse(d.isShorterThan(Duration.millis(9580)));

a. never failsb. usually failsc. always failsd. TimeOutException

Page 21: Java Time Puzzlers

import org.joda.time.DateTime;

import org.joda.time.Duration;

DateTime begin = new DateTime();

// watch me run 100 m

DateTime end = new DateTime();

Duration d = new Duration(begin, end);

assertFalse(d.isShorterThan(Duration.millis(9580)));

a. never failsb. usually failsc. always failsd. TimeOutException

Page 22: Java Time Puzzlers

import java.util.concurrent.TimeUnit;

import org.joda.time.Duration;

long begin = System.nanoTime(); // watch me run 100 m

long end = System.nanoTime(); Duration d = Duration.millis( TimeUnit.NANOSECONDS.toMillis(end – begin));

assertFalse(d.isShorterThan(Duration.millis(9580)));

Don't rely on System.currentTimeMillis(),and store an explicit duration.

Page 23: Java Time Puzzlers

import org.joda.time.*;

import org.joda.time.Interval;

import org.joda.time.LocalDate;

int steps = 6000;

LocalDate date = LocalDate.parse("2014-11-02"); DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles"); Interval interval = date.toInterval(zone);

long hours = interval.toDuration().getStandardHours();

assertEquals(240, steps / hours);

a. passesb. failsc. exceptiond. it depends

Page 24: Java Time Puzzlers

import org.joda.time.*;

import org.joda.time.Interval;

import org.joda.time.LocalDate;

int steps = 6000;

LocalDate date = LocalDate.parse("2014-11-02"); DateTimeZone zone = DateTimeZone.forID("America/Los_Angeles"); Interval interval = date.toInterval(zone);

long hours = interval.toDuration().getStandardHours();

assertEquals(240, steps / hours);

a. passesb. failsc. exceptiond. it depends

Page 25: Java Time Puzzlers

Is it a range?

Does local time

matter?

Need to add or subtract

time?

Elapsed time must be

accurate?Store duration

Store with zone offset

Store with zone ID

Store as UTC

Need to storea timestamp

no

no no

no

yes yes

yes yes

for begin and end

Store interval

Page 26: Java Time Puzzlers

Start at the beginning, and go on til you come to the end: then stop.

Illustration by John Tenniel, Alice in Wonderland