1

I'd like to print the difference between two dates in a form like "2 days, 3 hours, 5 minutes and 8 seconds".

I'm using this code calling the Joda-Time library but I've some troubles.

Calendar cal = Calendar.getInstance();
DateTime firstSeen = new DateTime(cal.getTime());

cal.add(Calendar.HOUR, 24*8);
cal.add(Calendar.MINUTE, 10);
cal.add(Calendar.SECOND, 45);

DateTime lastSeen = new DateTime(cal.getTime());
Period period = new Period(firstSeen, lastSeen);

PeriodFormatter daysHoursMinutesSeconds = new PeriodFormatterBuilder()
    .appendDays()
    .appendSuffix(" day", " days")
    .appendSeparator(", ")
    .appendMinutes()
    .appendSuffix(" minute", " minutes")
    .appendSeparator(" and ")
    .appendSeconds()
    .appendSuffix(" second", " seconds")
    .toFormatter();

String periodFormatted;
periodFormatted = daysHoursMinutesSeconds.print(period);
System.out.println(periodFormatted);

What should be printed is "8 days, 10 minutes and 45 seconds". Instead I get "1 day, 10 minutes and 45 seconds"; It seems the days overflow into the week. How can I tell the formatter to ignore the overflows and sum what overflows into the first unit?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
user2714602
  • 231
  • 4
  • 16

1 Answers1

2

This is the correct output, because the period is "1 week 1 day, 45 minutes" and week field is not printed:

package com.stackoverflow.so21002436;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

public class App {
    public static void main(final String[] args)
    {
        final DateTime firstSeen = DateTime.now();
        final DateTime lastSeen = firstSeen.plusDays(8).plusMinutes(10).plusSeconds(45);

        final Period period = new Period(firstSeen, lastSeen);
        System.err.println(period); // P1W1DT10M45S, ie. 1 day, 10 minutes and 45 seconds

        final PeriodFormatter daysHoursMinutesSeconds = new PeriodFormatterBuilder().appendDays()
                .appendSuffix(" day", " days")
                .appendSeparator(", ")
                .appendMinutes()
                .appendSuffix(" minute", " minutes")
                .appendSeparator(" and ")
                .appendSeconds()
                .appendSuffix(" second", " seconds")
                .toFormatter();

        final String periodFormatted = daysHoursMinutesSeconds.print(period);
        System.out.println(periodFormatted);
    }
}

or use a specific PeriodType:

package com.stackoverflow.so21002436;

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;

public class App {
    public static void main(final String[] args)
    {
        final DateTime firstSeen = DateTime.now();
        final DateTime lastSeen = firstSeen.plusDays(8).plusMinutes(10).plusSeconds(45);

        final Period period = new Period(firstSeen, lastSeen, PeriodType.dayTime());
        System.err.println(period); // P8DT10M45S, ie. 8 days, 10 minutes and 45 seconds

        final PeriodFormatter daysHoursMinutesSeconds = new PeriodFormatterBuilder().appendDays()
                .appendSuffix(" day", " days")
                .appendSeparator(", ")
                .appendMinutes()
                .appendSuffix(" minute", " minutes")
                .appendSeparator(" and ")
                .appendSeconds()
                .appendSuffix(" second", " seconds")
                .toFormatter();

        final String periodFormatted = daysHoursMinutesSeconds.print(period);
        System.out.println(periodFormatted);
    }
}

see Period(ReadableInstant, ReadableDuration, PeriodType)

  • Nearly perfect the second solution. Just one question: if I already have a period object(created without PeriodType.dayTime()) how can I manipulate it to have the same behaviour as the period object was created with PeriodType.dayTime()? – user2714602 Jan 08 '14 at 18:22
  • As indicated in the linked javadoc, there's a copy constructor, [`Period(Object period, PeriodType type)`](http://joda-time.sourceforge.net/apidocs/org/joda/time/Period.html#Period%28org.joda.time.ReadableInstant,%20org.joda.time.ReadableDuration,%20org.joda.time.PeriodType%29) –  Jan 08 '14 at 18:30