108

I am trying to use the Duration class instead of long. It has superior literal syntax. I like its flexibility, though it looks weird.

"PT10S" means 10 seconds, what is the problem to accept "10 seconds"?! Okay never mind.

I am just curious why PT prefix has been chosen (not "DU" e.g.) and why any prefix is better here rather than nothing?

1
  • 12
    This is the standard ISO-8601 notation for durations / periods.
    – Jesper
    Commented Jul 4, 2018 at 7:25

3 Answers 3

149

As can be found on the page Jesper linked to (ISO-8601 - Data elements and interchange formats – Information interchange – Representation of dates and times)

P is the duration designator (for period) placed at the start of the duration representation.
Y is the year designator that follows the value for the number of years.
M is the month designator that follows the value for the number of months.
W is the week designator that follows the value for the number of weeks.
D is the day designator that follows the value for the number of days.
T is the time designator that precedes the time components of the representation.

So P means 'Period' and because there are no date-components it only has a 'Time'.

You could interpret this as 'Period of Time'

The 'why' this was chosen, you have to ask the ISO members that wrote the standard, but my guess is that it is easier to parse. (short and unambigious)

The details for the time component are:

H is the hour designator that follows the value for the number of hours.
M is the minute designator that follows the value for the number of minutes.
S is the second designator that follows the value for the number of seconds. 

The value of PT20S then parses to:

  • Period
  • Time
  • 20
  • Seconds

So, a duration of 20 seconds.

More examples can be found in the javadoc: https://docs.oracle.com/javase/8/docs/api/java/time/Duration.html#parse-java.lang.CharSequence-

5
  • 18
    In other words, the P marks the beginning (presumably short for “Period”), and the T separates the years-months-days portion from the hours-minutes-seconds portion. For a value without any years-months-days, you end up with the PT at the beginning. Commented Jul 4, 2018 at 7:40
  • 2
    No, PT doesn't stand for Period of Time. It's just Period without a date component, only the time. The weird thing is that in java Period and Duration both have this P in front although Duration will not have the date component only the time, therefore for Duration you will have PT always and for Period you can have PYMWDTHMS
    – ACV
    Commented Nov 1, 2019 at 23:03
  • 1
    Thanks @ACV. You're saying its a Period and because there is no YMWD this means 'Period with only a Time component', which I freely translated to Period of Time. I'll update my answer to be more precise. Commented Nov 4, 2019 at 7:51
  • @RobAu you are right. And it's not so important. Actually Period of Time sounds easier to remember
    – ACV
    Commented Nov 4, 2019 at 13:28
  • 1
    To be precise: T means: the following components are time components.
    – MC Emperor
    Commented Jun 28, 2022 at 14:29
18

Java has taken a subset of the ISO 8601 standard format for a duration. So the “why” is why the standard was written the way it is, and it’s a guessing game. My go is:

  • P for period was chosen so that you can distinguish a duration from a date and/or time. Especially since a period may also be written in the same format as a local date-time, for example P0003-06-04T12:30:05 for 3 years 6 months 4 days 12 hours 30 minutes 5 seconds, the P can be necessary to distinguish. The P also gives a little but quick and convenient bit of validation in case you happen to pass a completely different string in a place where a duration was expected. And yes, PT10S looks weird, but once you get accustomed to it, you recognize it immediately as a duration, which can be practical.
  • T for time between the date part and the time part was chosen for two reasons:
    • For consistency with date-time strings that have T in the same place, for example 2018-07-04T15:00 for July 4, 2018 at 15:00 hours.
    • To disambiguate the otherwise ambiguous M for either months or minutes: P3M unambiguously means 3 months while PT3M means 3 minutes.
8

Actually if go on Duration API developed in Java since 1.8, they have gone with standard ISO 8601:

with java doc as below  :

/**
 * Applies an ISO 8601 Duration to a {@link ZonedDateTime}.
 *
 * <p>Since the JDK defined different types for the different parts of a Duration
 * specification, this utility method is needed when a full Duration is to be applied to a
 * {@link ZonedDateTime}. See {@link Period} and {@link Duration}.
 *
 * <p>All date-based parts of a Duration specification (Year, Month, Day or Week) are parsed
 * using {@link Period#parse(CharSequence)} and added to the time. The remaining parts (Hour,
 * Minute, Second) are parsed using {@link Duration#parse(CharSequence)} and added to the time.
 *
 * @param time   A zoned date time to apply the offset to
 * @param offset The offset in ISO 8601 Duration format
 * @return A zoned date time with the offset applied
 */
public static ZonedDateTime addOffset(ZonedDateTime time, String offset) { }

Obtains a Duration from a text string of pattern: PnDTnHnMn.nS, where
nD = number of days,
nH = number of hours,
nM = number of minutes,
n.nS = number of seconds, the decimal point may be either a dot or a comma.
T = must be used before the part consisting of nH, nM, n.nS


Example of implementation with java as 

import java.time.Duration;

public class ParseExample {

    public static void main(String... args) {
        parse("PT20S");//T must be at the beginning to time part
        parse("P2D");//2 day
        parse("-P2D");//minus 2 days
        parse("P-2DT-20S");//S for seconds
        parse("PT20H");//H for hours
        parse("PT220H");
        parse("PT20M");//M for minutes
        parse("PT20.3S");//second can be in fraction like 20.3
        parse("P4DT12H20M20.3S");
        parse("P-4DT-12H-20M-20.3S");
        parse("-P4DT12H20M20.3S");
    }

    private static void parse(String pattern) {
        Duration d = Duration.parse(pattern);
        System.out.println("Pattern: %s => %s%n", pattern, d);
    }
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.