4

I have an issue with date/time age calculations on Android Studio. I have used calander instance and it seemed to work for the most part but every now and then it seems to be Inaccurate.

I switched to LocalDate which looks way cleaner but, as far as I can tell through my research is only supported by API 26 and higher. I think Joda Time has the same issue.

My question is this: What is the best method to calculate the elapsed time between two dates that is the most accurate (factoring in leap years, months with different number of days, etc) and is supported by lower API versions (ie 17 and up)?

I have been researching and it appears that the answer may be the basic calander instance but then I come back to reliability and accuracy issue. Any input would be greatly appreciated.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Stark
  • 107
  • 1
  • 11
  • Maybe using 3rd-party libraries (ThreetenABP, Joda-Time for Android or Time4A)? – Meno Hochschild Jan 30 '18 at 17:01
  • Thank you Meno, yeah I had the same issue with Joda-Time but I will try it again... – Stark Jan 30 '18 at 19:30
  • For age calculations I would recommend: a) ThreetenABP (backport of java.time) => `ChronoUnit.YEARS.between(LocalDate, LocalDate)` or b) Time4A (bigger lib with more features) => `CalendarUnit.YEARS.between(PlainDate, PlainDate)` – Meno Hochschild Jan 31 '18 at 03:55

1 Answers1

3

tl;dr

Use the ThreeTenABP library in work with earlier versions of Android.

Period.between(
    LocalDate.of( 2017 , Month.JUNE , 23 ) , 
    LocalDate.now( ZoneId.of( “Europe/Paris” ) )
)

Use java.time

The original date-time classes bundled with the earliest versions of Java were well-intentioned but are an awful ugly confusing mess. Always avoid Date, Calendar, etc.

Joda-Time was an amazing industry-leading effort to make a serious robust date-time framework. Its principal author, Stephen Colebourne, went on to use the lessons learned there to produce its successor, the java.time classes built into Java 8 & 9, defined by JSR 310. The Joda-Time project is now in maintenance mode, and migration to java.time is advised.

Much of the java.time functionality is back-ported to Java 6 and Java 7 in the ThreeTen-Backport project. That project includes a utility class for converting to/from the legacy types so your new code may interoperate with old existing code. Further adapted for earlier Android in the ThreeTenABP project.

For example, on the Java platform you would call:

java.time.LocalDate localDate = java.time.LocalDate.of( 2018 , 1 , 23 ) ; // January 23rd, 2018.

…whereas on early Android using the ThreeTen-Backport/ThreeTenABP projects you would call:

org.threeten.bp.LocalDate localDate = org.threeten.bp.LocalDate.of( 2018 , 1 , 23 ) ; // January 23rd, 2018.

Span of time

To calculate elapsed time as a span of time unattached to the timeline, use either:

  • Period for years, months, days
  • Duration for hours, minutes, seconds, and fractional second in nanoseconds.

More simply put…

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Basil, thank you... the problem I am running into is with the LocalDate.of(year, month, day) that is where I get the error on the "of" saying that it requires API 26 or higher... I am still looking into it though. I don't want to go back to the Date, Calendar... etc.. – Stark Jan 30 '18 at 21:57
  • @ErrolNiel An implementation of *java.time* (JSR 310) was added to only the latest versions of Android. If your project is set to build for earlier versions of Android, you have no `LocalDate` class available, and thus a compiler error for calling `LocalDate.of`. As an alternative, you must **add a library to your project** as a substitute for the absent java.time classes. That library is *ThreeTen-Backport*, packaged as *ThreeTenABP* for Android. Instead of calling `java.time.LocalDate.of`, you call `org.threeten.bp.LocalDate.of`. Use `import` statements such as `import org.threeten.bp.* ;` – Basil Bourque Jan 30 '18 at 22:31
  • Thank you Basil, I will try that. I will look up the necessary imports for ThreeTenABP. – Stark Jan 31 '18 at 01:53