javadurationminutetime4j

How to convert a Time4J Duration to a count of minutes?


How do I convert a Time4J Duration<ClockUnit> to a number of minutes? I’m fine with truncating any seconds, I just want the whole minutes. A couple of simple examples probably explain the best:

There isn’t any toMinutes method (like there is in java.time.Duration). I played around with a Normalizer, the getTotalLength method and a stream operation and got a 6 lines solution to work, but surely there is a simpler way?

The solutions for hours and seconds could also be interesting, but I expect them to be more or less trivial modifications of the solution for minutes.

Link: Documentation of net.time4j.Duration


Solution

  • Normalize to minutes and use getPartialAmount()

    We do need the normalizer. We get it from ClockUnit.only(). Then getPartialAmount() takes care of the rest.

        List<Duration<ClockUnit>> durations = Arrays.asList(
                Duration.of(1, ClockUnit.HOURS),
                Duration.of(34, ClockUnit.SECONDS));
        
        for (Duration<ClockUnit> dur : durations) {
            long minutes = dur.with(ClockUnit.MINUTES.only())
                    .getPartialAmount(ClockUnit.MINUTES);
            System.out.format("%s = %d minutes%n", dur, minutes);
        }
    

    Output:

    PT1H = 60 minutes
    PT34S = 0 minutes
    

    As explained in the tutorial (link at the bottom), Time4J is mainly designed around chronological elements (or fields) like years, months, and yes, minutes. So in code we first need to convert the duration to a duration of only minutes, after which we can take out the value of the minutes element — now the only element in the duration (in the case of 14 seconds, there isn’t even any minutes element, but getPartialAmount() sensibly returns 0 in this case).

    We should obviously wrap the conversion into a method:

    private static final long durationToNumber(Duration<ClockUnit> dur, ClockUnit unit) {
        return dur.with(unit.only()).getPartialAmount(unit);
    }
    

    As a bonus this method gives us the conversion to hours or seconds for free:

        for (Duration<ClockUnit> dur : durations) {
            long hours = durationToNumber(dur, ClockUnit.HOURS);
            long seconds = durationToNumber(dur, ClockUnit.SECONDS);
            System.out.format("%s = %d hours or %d seconds%n", dur, hours, seconds);
        }
    
    PT1H = 1 hours or 3600 seconds
    PT34S = 0 hours or 34 seconds
    

    Link

    Time4J Tutorial: Element centric approach