Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Simplifying Date/Time Calculations with the Java 8 java.time API (nee Joda-Time, JSR-310)

Author: Ian Darwin
Published? true -- FormatLanguage: W

Problem:

You've heard that JSR-310 date/time API, included in Java SE 8, simplifies date and time calculations, and you'd like to use it in Android.

Solution:

Since Android refused to be compliant with JDK8, you can use the JSR-310 "backport" and gain access to all the java.time facilities, albeit with a different package name.

Discussion:

There is a long history to the 'java.time' API which I won't bore you with here; suffice to say that we are all indebted to Steven Colbourne for inventing it and for his constancy in urging first Sun, then Oracle, to incorporated into Java, which finally happened in Java 8.

For licensing reasons, the "backport" of JSR-310 - by its original author- to Java 6/7 was placed in a non-Java package, `org.threeten.bp`

Since Android doesn't provide full compatability with Java 8, we use an external library. While it is possible to use the original backport on Android as well as on standard Java, we'll use an Android-speicifc version that uses a much more efficient mechanism for loading the timezone information. This version, by Jake Wharton, is available on GitHub at https://github.com/JakeWharton/ThreeTenABP. More interestingly, it can be added to any Gradle or Maven project just by adding the coordinates `compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'` to your build script (the version number may change over time, of course).

Here is an example to show you the level of complexity of the kind of calculations that are _built in_; it shows figuring out the day of the month that the next weekly and monthly pay days occur on.


       LocalDateTime now = LocalDateTime.now();
       LocalDateTime weeklyPayDay =
               now.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
       weekly.setText("Weekly employees' payday is Friday " +
               weeklyPayDay.getMonth() + " " +
               weeklyPayDay.getDayOfMonth());
       LocalDateTime monthlyPayDay =
               now.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY));
       monthly.setText("Monthly employees are paid on " +
               monthlyPayDay.getMonth() + " " +
               monthlyPayDay.getDayOfMonth());

The API includes LocalDate objects, which just represent a day of time, LocalTime which is just a time of day, and LocalDateTime, which represents a date and a time. Both are, as the name implies, Local, not meant to represent time across the world's time zones. For that, you want to use one of several classes that represent time zones. See https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html for details of all the classes.

To use this on Android you do need one call to initialize it, either in your Application class (see <<r1218>>) or in your Activity. In the main activity's `oncreate` method you'd say:


AndroidThreeTen.init(getApplication());


The result should look like this:

See Also:

The new API is covered in Chapter 6 of my Java Cookbook (see http://javacook.darwinsys.com/) and in some tutorials on the web. Make sure you use the version of the tuturial corresponding to the API you are using. Java 8 version differ from "threeten" versions and these both differ from the original Joda Time versions.

Download:

The source code for this project is in the Android Cookbook repository at http://github.com/IanDarwin/Android-Cookbook-Examples, in the subdirectory JavaTimeDemo.
No records found.