1

I'm building my first I/O app as a learning exercise in java. It will be for tracking fitness and running records.

When a user is entering a new workout they will be asked to enter how long the run took them (eg 01h 02min 45sec). The only way I know how to store Date/Time in Java is with the Date class which involves miliseconds since the epoch etc...

Are there any Classes available for simply creating basic "time" objects so I can store 20min30secs in an understandable format instead of a double (eg. 20.5mins).

Cheers!

Dean Sherwin
  • 478
  • 5
  • 13
  • If you're using Java 8 (and if it's a new project, there's no reason not to), then [this](https://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) should help. – biziclop Feb 10 '16 at 18:24
  • A Duration would be a good match: https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html – assylias Feb 10 '16 at 18:25
  • 1
    Why don't you save start and finish instant, then when you need to show "20min30secs" you simply compare finish with start? Exact instants may be useful in other situations (show total miles of a week, miles per day, etc). – andrucz Feb 10 '16 at 18:26
  • Do you speak about Android App ? – alex Feb 10 '16 at 18:42
  • Just building a simple .jar app for my PC – Dean Sherwin Feb 10 '16 at 19:23

2 Answers2

3

Yes, if you're using Java 8 then java.time.Duration is the best choice. For versions before 8, use org.joda.time.Duration.

Both these classes have built in methods to input minutes and seconds and to extract the total number of milliseconds, which would be a good choice for a storage format in a run tracking application

As an example, here's how to create a java.time.Duration of 30 minutes, and then extract the total number of milliseconds, which you can store in a database etc:

Duration activityDuration = Duration.ofMinutes(30);
System.out.println(activityDuration.toMillis()); // prints 1800000
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Colin Pickard
  • 45,724
  • 13
  • 98
  • 148
  • Thank you very much! I knew there had to be a built in functionality for this but my googling got me nowhere! :) – Dean Sherwin Feb 10 '16 at 18:39
  • Be aware that the java.time classes have a resolution of [nanoseconds](https://en.wikipedia.org/wiki/Nanosecond), up to nine digits after the decimal point of a fractional second. Milliseconds take only 3 digits after the decimal point. Joda-Time and java.util.Date have millisecond resolution. – Basil Bourque Feb 10 '16 at 20:04
0

The Answer by Colin Pickard is correct.

I'll add two issues:

  • java.time.Duration does not offer getter methods (not yet).
  • There is also another way to input and output such values.

Getter Methods

The current implementation of java.time as of Java 8 Update 74 has no getter methods to interrogate a Duration object for each part, the hours, the minutes, and the seconds.

A java.time.Duration is structured as two parts internally, a total number of seconds plus an adjustment of a number of nanoseconds (a fractional second):

  • To get the fractional second as a count of nanoseconds: getNano
  • To translate the Duration as a count of whole seconds: getSeconds

From there you can do the math yourself (see below).

Java 9 brings such getter methods, according to this OpenJDK page, Add java.time.Duration methods for days, hours, minutes, seconds, etc.. For more info, see this Question, Why can't I get a duration in minutes or hours in java.time?.

You can look at the source code to help you do the math as mentioned above.

Seems to be something like this:
[Beware! I've not run this, just my own pseudo-code. Please edit to fix and improve.]

  • Days part: ( getSeconds() / 86400 ) ( 86400 seconds in generic 24-hour day)
  • Hours part: ( int ) ( toHours() % 24 )
  • Minutes part: ( int ) ( toMinutes() % 60 ) ( 60 minutes per hour )
  • Seconds part: ( int ) ( getSeconds() % 60 ) ( 60 seconds per minute )
  • Milliseconds part: ( int ) ( getNano() / 1_000_000 )

ISO 8601

The ISO 8601 standard defines sensible unambiguous text formats for representing various kinds of date-time values.

They have a format for durations in this structure: PnYnMnDTnHnMnS where the P marks the beginning (‘p’ for Period, a synonym) and the T in the middle separates year-month-day portion from the hours-minutes-seconds. Split seconds are represented as a decimal fraction, with digits following after the decimal point (a period or a comma).

For example, P3Y6M4DT12H30M5S represents a duration of three years, six months, four days, twelve hours, thirty minutes, and five seconds.

Your 20min30secs example would be PT20M30S.

Input-Output

Both the java.time and Joda-Time frameworks use ISO 8601 by default when parsing/generating String representations of their date-time values.

String input = "PT20M30S";
Duration duration = java.time.Duration.parse ( input );

Dump to console.

System.out.println ( "input: " + input + " | duration: " + duration.toString() );

input: PT20M30S | duration: PT20M30S

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154