Duration
An ISO 8601 compliant duration type.
Syntax
A duration literal starts with the character P
(for period) followed by one or more values.
Character T
separates the date and time portions of the duration literal, similarly to the ISO 8601 datetime format.
Date value unit designators:
-
Y
: years, -
M
: months, -
W
: weeks, -
D
: days.
Time value unit designators:
-
H
: hours, -
M
: minutes, -
S
: seconds.
As per the standard, weeks cannot be specified alongside other units. |
Seconds can be specified as a decimal fraction, with precision up to nanoseconds (9 digits after the decimal point). Values for all other units are expected to be integers.
# 12 weeks
P12W
# 1 year, 2 months, 3 days, 4 hours, 5 minutes, 6 seconds, and 789 milliseconds
P1Y2M3DT4H5M6.789S
# not allowed
# P1W1D
# Even though `M` can mean either months or minutes,
# they are disambiguated by the time designator `T`
P1M # one month
PT1M # one minute
Storage representation
A duration value is stored as three integer parts: 32 bits of months, 32 bits of days, and 64 bits of nanoseconds. In particular, no
conversion between the parts is performed: P1D
is not always equal to PT24H
, nor can P1M
be converted to any fixed number of days
without having a date as a frame of reference.
In expressions
When adding to or subtracting from a datetime or a datetime-tz value, first the months part is added, then the days, and finally the nanoseconds. These operations respect daylight saving changes, and other timezone changes where relevant.
This means that addition of durations to datetimes is not commutative.
To avoid confusion, it is generally recommended to compute the duration value first, then add it to or subtract it from the datetime. |
If adding a month would make the day of the month invalid, the last day of the resulting month is used instead.
# 31st of January + 1 month = 28th of February, not 31st of February or 3rd of March
2025-01-31T14:00:00Z + P1M == 2025-02-28T14:00:00Z
When used with a value of type datetime-tz, arithmetic operations with duration respect local timezone changes (e.g. daylight saving time).
# London DST change occurred on 2024-03-31 01:00:00 GMT
2024-03-30T12:00:00 Europe/London + P1D == 2024-03-31T12:00:00
2024-03-30T12:00:00 Europe/London + PT24H == 2024-03-31T13:00:00
If adding months and days results in an ambiguous datetime in the time zone, the earlier datetime is used.
# London DST change occurred on 2024-10-27 02:00:00 BST
# I.e., on 2024-10-27, the time span between 01:00:00 and 02:00:00 occurs twice
2024-10-26T01:30:00 Europe/London + P1D == 2024-10-27T01:30:00 BST
# Between these two local datetimes, the earliest is BST
2024-10-26T01:30:00 Europe/London + PT24H == 2024-10-27T01:30:00 BST
2024-10-26T01:30:00 Europe/London + PT25H == 2024-10-27T01:30:00 GMT
If adding months and days results in a datetime that does not exist in the time zone, i.e. if there is a gap in the time zone, the datetime is increased by the length of the gap.
# London DST change occurred on 2024-03-31 01:00:00 GMT
# I.e., there is a gap on 2024-03-31 between 01:00:00 and 02:00:00
2024-03-30T01:30:00 Europe/London + P1D == 2024-03-31T02:30:00 BST
# This is the same as adding 24 hours
2024-03-30T01:30:00 Europe/London + PT24H == 2024-03-31T02:30:00 BST
The nanosecond part of the duration is added directly to the underlying UTC timestamp, and as such requires no special handling.