Home » Java » My PeriodFormatter is not behaving as I expect – what have I done wrong?

My PeriodFormatter is not behaving as I expect – what have I done wrong?

Posted by: admin December 28, 2021 Leave a comment

Questions:

I’m having trouble using Joda Time’s PeriodFormatter. I want one to report days, hours, minutes and seconds but my attempt seems to be wrapping around weeks. What should I be doing differently?

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

public class Problems {

    public static void main(String[] args) {

        PeriodFormatter formatter = new PeriodFormatterBuilder()
            .printZeroNever()
            .appendDays()
            .appendSuffix(" day", " days")
            .appendSeparator(", ")
            .appendHours()
            .appendSuffix(" hour", " hours")
            .appendSeparator(", ")
            .appendMinutes()
            .appendSuffix(" minute", " minutes")
            .appendSeparator(", ")
            .appendSeconds()
            .appendSuffix(" second", " seconds")
            .toFormatter();

        DateTime now = new DateTime();
        DateTime justUnderAWeekAgo = now.minusDays(7).plusMinutes(1);
        DateTime justOverAWeekAgo = now.minusDays(7).minusMinutes(1);
        System.out.println(now);
        System.out.println(justUnderAWeekAgo);
        System.out.println(justOverAWeekAgo);
        // I am happy with the following:
        System.out.println(
            formatter.print(new Period(justUnderAWeekAgo, now)));
        // But not with this (outputs "1 minute" but I want "7 days, 1 minute"):
        System.out.println(
            formatter.print(new Period(justOverAWeekAgo, now)));
    }
}

EDIT: I guess I can see why this isn’t working – i.e. that the formatter just prints the Period’s various values, and since Periods store a value for weeks, the value for days on my problem period is indeed 0. But I still need a good way of doing this…

Answers:

The problem in your case is that you do not ask your PeriodFormatter to display the weeks.

Two possibilities:

Solution 1: Display the weeks:

PeriodFormatter formatter = new PeriodFormatterBuilder()
        .printZeroNever()
        .appendWeeks()
        .appendSuffix(" week", " weeks")
        .appendSeparator(", ")
        .appendDays()
        .appendSuffix(" day", " days")
        .appendSeparator(", ")
        .appendHours()
        .appendSuffix(" hour", " hours")
        .appendSeparator(", ")
        .appendMinutes()
        .appendSuffix(" minute", " minutes")
        .appendSeparator(", ")
        .appendSeconds()
        .appendSuffix(" second", " seconds")
        .toFormatter();

The second output in your example will be:

1 week, 1 minute

Solution 2: Display only the days so you will have to use the PeriodType.yearMonthDayTime():

new Period(justUndeAWeekAgo, now, PeriodType.yearMonthDayTime());

Using this second solution, you can keep your PeriodFormatter as it is now. The second output in your example will then be:

7 days, 1 minute