Modern Date/Time
APIs on Android
Droidcon Bucharest 2016
Alex Florescu
@flor3scu
YPlan
Slide 2
Slide 2 text
Overview
• Why
• Joda time and JSR-310
• What can you do with them
• Setup & testing
• Good and bad
Slide 3
Slide 3 text
Date and Time is hard
• Timezones
• Daylight savings
• Different calendar systems
• Leap days/seconds/etc
• AND MORE
Slide 4
Slide 4 text
Quiz: Leap years
• A leap year (e.g. 2016) adds a day, February 29th
• What years are leap years?
Slide 5
Slide 5 text
Quiz: What is a leap year?
• Divisible by four
Slide 6
Slide 6 text
Quiz: What is a leap year?
• Divisible by four
• But NOT divisible by 100
Slide 7
Slide 7 text
Quiz: What is a leap year?
• Divisible by four
• But NOT divisible by 100
• UNLESS divisible by 400
Slide 8
Slide 8 text
What’s wrong with Java 6
Date?
Slide 9
Slide 9 text
java.util.Date
Date someDate = new Date(1967, 5, 10);
System.out.println(someDate);
// What date is this?
May 10th 1967
June 11th 1967
October 5th 1967
November 6th 1967
Slide 10
Slide 10 text
java.util.Date
Date someDate = new Date(1967, 5, 10);
System.out.println(someDate);
Answer: June 10th 3867
Year: years from 1900
Month: 0-indexed
Day: 1-indexed
Slide 11
Slide 11 text
Java 6 Date/Time API
• Mutable
• 0-indexed months
• Little support for simple operations
• No representation for duration, non-time-zone
dates, only dates, only times etc.
Slide 12
Slide 12 text
JVM Alternatives
• Joda Time
• Since 2004
• De-facto date/time solution pre-Java 8
• JSR-310 / Java 8 API
• Released in 2014
• Same project lead as Joda Time
• Official API for Java 8, backported to Java 6
Slide 13
Slide 13 text
Joda time
• Still actively maintained
• For new projects use Java 8 API
• See comparison and Stephen Colebourne’s blog
Slide 14
Slide 14 text
Joda time on Android
• Can use directly, but large memory footprint
• See problem description
• Solution: https://github.com/dlew/joda-time-android
• Method count: 5053
Slide 15
Slide 15 text
JSR-310 / Java 8 API
• Official JVM solution (>= Java 8)
• Built with experience from Joda time
• Generally better performance
• Smaller package, fewer methods
Slide 16
Slide 16 text
ThreeTen on Android
• Backport library “ThreeTen”, Java 6 compatible
• Same problem as Joda if use JVM lib directly
• Use: https://github.com/JakeWharton/ThreeTenABP
• Method count: 3278
Slide 17
Slide 17 text
Setup
• In build.gradle:
compile
'com.jakewharton.threetenabp:threetenabp:1.0.3'
• In Application.onCreate():
@Override public void onCreate() {
super.onCreate();
AndroidThreeTen.init(this);
}
Slide 18
Slide 18 text
Cool things
ZonedDateTime.now();
//2016-03-12T12:11:25.371+02:00
[Europe/Bucharest]
ZonedDateTime.now(ZoneId.of("Europe/
London"));
//2016-03-12T10:11:26.374+00:00
[Europe/London]
Slide 19
Slide 19 text
Cool things
LocalDateTime now = LocalDateTime.now();
LocalDate tomorrowDay =
now.toLocalDate().plusDays(1);
LocalDateTime noonTomorrow =
tomorrowDay.atTime(12, 0);
Slide 20
Slide 20 text
Cool things
LocalTime now = LocalTime.now();
LocalTime lunchTime =
LocalTime.of(12, 30);
if (now.isAfter(lunchTime)) {
// GO TO LUNCH
}
Slide 21
Slide 21 text
Testing
• UI tests — just test the app
• Robolectric tests — initialise with Robo context
• Plain JUnit tests — use JVM back port
testCompile 'org.threeten:threetenbp:
1.3.1'
Slide 22
Slide 22 text
Testing
• Note: Can’t mix Robolectric and plain JUnit tests
• Separate plain JUnit and Robolectric tests
• If using ThreeTenABP in a module/configuration, all
tests (that involve ThreeTen) must be Robolectric
Slide 23
Slide 23 text
Why should you use?
• Safer, clearer, fluent API
• Easier to do everything
• Immutable
• Excellent timezone support
Slide 24
Slide 24 text
Any negatives?
• Immutable (Android GC’ing is not JVM GC’ing)
• 5% towards DEX limit
• Need to connect old and new APIs
• Android specific locale issues (e.g. 24-hr toggle)
Slide 25
Slide 25 text
More docs
• ThreeTen Reference
• JavaDoc
Slide 26
Slide 26 text
Thank you
• Slides: http://bit.do/AlexDroidconRo
• T: @flor3scu