We generally prefer to use the Joda-Time library to handle date and time data.
plusHours, plusDays etcLocalDate, LocalTime etc)toString/parse conversions to/from ISO stringsMost introductions and snippets about Joda-Time illustrate the core DateTime class, which combines a date, time and timezone.
DateTime now = new DateTime(2015, 4, 13, 9, 15, 0); // use default timezone
DateTime laterToday = now.withTime(17, 30, 0, 0);
DateTime tomorrow = now.plusDays(1);
DateTime muchLater = now.plusMonths(6);
Date + Time + Timezone ⇌ Instant (epoch millis)
Date + Time + Timezone ⇌ Instant (epoch millis)
What is the corresponding instant to 2015-03-29T01:30:00 in Europe/London timezone?
How about 2015-10-25T01:30:00 ?
DateTime dt = new DateTime(2014, 12, 31, 11, 24, 15); // Europe/London
// dt.toString() : "2014-12-31T11:24:15.000Z"
DateTime dt2 = DateTime.parse("2014-12-31T11:24:15Z");
// dt2.toString() : "2014-12-31T11:24:15.000Z"
DateTime dt = new DateTime(2015, 4, 13, 9, 15, 0); // Europe/London
// dt.toString() : "2015-04-13T09:15:00.000+01:00"
DateTime dt2 = DateTime.parse("2015-04-13T09:15:00+01:00");
// dt2.toString() : "2015-04-13T09:15:00.000+01:00"
assertThat(new DateTime(2008, 6, 1, 14, 0, 0) /* Europe/London */,
equalTo(DateTime.parse("2008-06-01T14:00:00+01:00")));
Expected: <2008-06-01T14:00:00.000+01:00>
but: was <2008-06-01T14:00:00.000+01:00>
what
These DateTime instances do represent the same time instant, with the same time zone offset, but not the same time zone ruleset.
Parsing a time with +01:00 or Z as a suffix resolves to a fixed-offset "time zone".
Unfortunately the ruleset isn't clearly indicated in the toString() output, so it's easy to miss the distinction.
There is in fact an org.joda.time.Instant class. This purely encapsulates an instant, free of any concept of timezone.
assertThat(new DateTime(2008, 6, 1, 14, 0, 0).toInstant(),
equalTo(Instant.parse("2008-06-01T14:00:00+01:00")));
This is likely a more suitable type to correspond to timestamps in databases, event structures...
Instant does not have those oh-so-convenient plusDays, plusHours etc methods.
You have to convert to DateTime to do that sort of manipulation.
This pushes you to supply a timezone context.
Instant will be formatted as UTC by a DateTimeFormatter unless that formatter has an override zone.
Arguably not a bad thing, but not what I expected.
Also has Instant, and emphasises separation of machine-timeline with human date/times more strictly.
DateTime becomes ZonedDateTime and/or OffsetDateTime, emphasising what they contain.
ZonedDateTime includes the time zone ruleset name in its toString() if it is not a fixed offset.
As per Colebourne's blog entry, DateTime implementing
ReadableInstant has come to be seen as a mistake (#1 on the list).