2

Is there a hidden way to get a Joda-Time period in minutes (or any other)

Right now I do:

(period.getHours()*60 + period.getMinutes() + roundTwoDecimals((double)(period.getSeconds()/60)))
double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
    return Double.valueOf(twoDForm.format(d));
}

But for some reason I think there could be an easier way.

EDIT: My times will be max hours, and will never be days. This is my first time with Joda-Time.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Juan
  • 521
  • 1
  • 11
  • 28
  • 1
    The number of minutes in a period depends on it being associated with a particular instant in time. What if the period were to span a leap year, or a leap second? The resulting values would be different. Is it possible for you to use a [`Duration`](http://joda-time.sourceforge.net/apidocs/org/joda/time/Duration.html) instead? – Rob Hruska Jan 09 '12 at 19:12
  • 1
    For some clarification, have a look at [this answer](http://stackoverflow.com/a/6467975/29995) and [this answer](http://stackoverflow.com/a/2653655/29995). – Rob Hruska Jan 09 '12 at 19:13
  • Thanks for the links, even if I dont use duration this time they provided valuable knowledge. – Juan Jan 09 '12 at 20:04

3 Answers3

9

Since Periods are defined by individual component fields (e.g. 5 years, 7 weeks), they cannot (easily) be converted directly to, say, minute values without first associating them with a particular instant in time.

For example, if you have a period of 2 months, how many minutes does it contain? In order to know that, you need to know which two months. Perhaps:

  • June and July? (30 + 31 = 61 days)
  • July and August? (31 + 31 = 62 days)
  • February of a leap year and March? (29 + 31 = 60 days)

Each one of those is going to have a different number of minutes.

That in mind, there are a few ways to approach this. Here are a couple:

  1. If you're guaranteed that your Period won't contain months (or higher), you can just use toStandardSeconds():

    Period period = new Period(60, 40, 20, 500);
    System.out.println(period.toStandardSeconds().getSeconds() / 60.0);
    
    // outputs 3640.3333333333335
    

    However, if you do end up with a month value in your Period, you'll get (per the javadoc) an UnsupportedOperationException:

    java.lang.UnsupportedOperationException: Cannot convert to Seconds as this period contains months and months vary in length

  2. Otherwise, you can associate the Period with an instant in time and use a Duration:

    Period period = new Period(1, 6, 2, 2, 5, 4, 3, 100);
    
    // apply the period starting right now
    Duration duration = period.toDurationFrom(new DateTime());
    
    System.out.println(duration.toStandardSeconds().getSeconds() / 60.0);
    
    // outputs 810964.05 (when right now is "2012-01-09T13:36:43.880-06:00")
    

Note that #2 will print different values depending on the day the code runs. But that's just the nature of it.

As an alternative, you might consider just using Durations from the start (if possible) and not using Periods at all.

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
  • My program "durations" will only be between minutes and a couple of hours, and reading the answers seems like I should had gone durations from the start. But considering that is already written do you think method #1 would just be an easy fix? One last quesiton if I use period.toStandardminutes() wouldnt it be simpler? No need to add, and multiply the hours. – Juan Jan 09 '12 at 20:04
  • @Juan - #1 will probably be a good enough fix for your situation; it might not hurt to add a check around it for months (to avoid the unexpected `UnsupportedOperationException`) in case they happen to sneak in. As for `toStandardMinutes()`: I was using seconds because A) I wasn't sure if `toStandardMinutes()` would truncate the partial seconds, and B) if you needed those partial seconds. If you're okay with the truncation, using `toStandardMinutes()` is probably fine. – Rob Hruska Jan 09 '12 at 20:11
  • @Juan - *"Tried...but didnt work"* - how? Can you update your question with the code you tried, the result, and why it wasn't what was expected? – Rob Hruska Jan 09 '12 at 22:17
  • Okay, work. Seems there was a little error on a previous statement. Works using: roundTwoDecimals((double)(period.toStandardSeconds().getSeconds())/60) I had to leave the roundTwoDecimals and cast it to double, but still better – Juan Jan 09 '12 at 22:45
  • This accepted answer is needlessly complex. Look at the [`Minutes`](http://www.joda.org/joda-time/apidocs/org/joda/time/Minutes.html) class, as shown in [my answer](http://www.joda.org/joda-time/apidocs/index.html). A simple single line of code. – Basil Bourque Apr 09 '14 at 06:03
4

Yes, you can easily get minutes from a Joda-Time Period object.

int minutes = Minutes.standardMinutesIn( period ).getMinutes();

FYI, the Joda-Time project is now in maintenance-mode. Now recommended to migrate to its official successor: the java.time classes defined in JSR 310, and build into Java 8+.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • This worked perfectly for me, convert from seconds to minutes like in the accepted answer is not needed, this should be the accepted answer by its simplicity – erik.aortiz Mar 01 '23 at 23:33
2

You can try (double) period.getMillis()/60000 and reformat it.

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • 1
    This will only return the millisecond *component* of the period, and will disregard the other fields. – Rob Hruska Jan 09 '12 at 19:09
  • 2
    To clarify, doing `new Period(1, 6, 2, 2, 5, 4, 3, 100).getMillis()` will only return `100`, and not the full length of the period (i.e. summed fields). – Rob Hruska Jan 09 '12 at 19:14