57

I'm using the Joda-Time library with Java. I'm having some difficulty trying to turn a Period object to a string in the format of "x days, x hours, x minutes".

These Period objects are first created by adding an amount of seconds to them (they are serialized to XML as seconds and then recreated from them). If I simply use the getHours() etc. methods in them, all I get is zero and the total amount of seconds with getSeconds.

How can I make Joda calculate the seconds into the respective fields, like days, hours, etc...?

4 Answers4

92

You need to normalize the period because if you construct it with the total number of seconds, then that's the only value it has. Normalizing it will break it down into the total number of days, minutes, seconds, etc.

Edit by ripper234 - Adding a TL;DR version: PeriodFormat.getDefault().print(period)

For example:

public static void main(String[] args) {
  PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
    .appendDays()
    .appendSuffix(" day", " days")
    .appendSeparator(" and ")
    .appendMinutes()
    .appendSuffix(" minute", " minutes")
    .appendSeparator(" and ")
    .appendSeconds()
    .appendSuffix(" second", " seconds")
    .toFormatter();

  Period period = new Period(72, 24, 12, 0);

  System.out.println(daysHoursMinutes.print(period));
  System.out.println(daysHoursMinutes.print(period.normalizedStandard()));
}

Will print:

24 minutes and 12 seconds
3 days and 24 minutes and 12 seconds

So you can see the output for the non-normalized period simply ignores the number of hours (it didn't convert the 72 hours to 3 days).

Community
  • 1
  • 1
SteveD
  • 5,396
  • 24
  • 33
  • o.O ... I guess I should have been more verbose. – Jherico Sep 17 '09 at 22:18
  • 2
    -1 from me, because this is difficult to localise. – Hakanai Aug 02 '12 at 23:40
  • 8
    If you use gettext i do not see why this is diffucult to localize! +1 and ther is a method `withLocale(Locale locale)` which _Returns a new formatter with a different locale that will be used for printing and parsing._ – BigAl Aug 28 '12 at 08:48
  • 1
    I added this answer into your own, your answer is good but it's way too verbose for a lot of needs. http://stackoverflow.com/a/4862467/11236 – ripper234 May 06 '13 at 08:48
  • @ripper234 It does explain exactly how to use a PeriodFormatter, though. However, I did use your tl;dr. Thanks! – Erick Robertson Jul 17 '14 at 12:49
23

You can also use the Default formatter, which is good for most cases:

Period period = new Period(startDate, endDate);
System.out.println(PeriodFormat.getDefault().print(period))
simao
  • 14,491
  • 9
  • 55
  • 66
12
    Period period = new Period();
    // prints 00:00:00
    System.out.println(String.format("%02d:%02d:%02d", period.getHours(), period.getMinutes(), period.getSeconds()));
    period = period.plusSeconds(60 * 60 * 12);
    // prints 00:00:43200
    System.out.println(String.format("%02d:%02d:%02d", period.getHours(), period.getMinutes(), period.getSeconds()));
    period = period.normalizedStandard();
    // prints 12:00:00
    System.out.println(String.format("%02d:%02d:%02d", period.getHours(), period.getMinutes(), period.getSeconds()));
Jherico
  • 28,584
  • 8
  • 61
  • 87
2
PeriodFormatter daysHoursMinutes = new PeriodFormatterBuilder()
    .appendDays()
    **.appendSuffix(" day", " days")
    .appendSeparator(" and ")
    .appendMinutes()
    .appendSuffix(" minute", " minutes")**
    .appendSeparator(" and ")
    .appendSeconds()
    .appendSuffix(" second", " seconds")
    .toFormatter();

you're missing the hours, that's why. Append hours after days and problem solved.

LoveAndCoding
  • 7,857
  • 2
  • 31
  • 55
marucf
  • 21
  • 1