TypeDB 3.0 is live! Get started for free.

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.

Example duration literals
# 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.

# 29th of Februrary + 1 month and 1 day = 29th of March + 1 day = 30th of March
2024-02-29T12:00:00 + P1M1D == 2024-02-29T12:00:00 + P1M + P1D == 2024-03-30T12:00:00

# 29th of Februrary + 1 day + 1 month = 1st of March + 1 month = 1st of April
2024-02-29T12:00:00 + P1D + P1M == 2024-04-01T12:00:00

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.

Defining a duration valued attribute

define
  attribute event-cadence value duration;

Inserting a duration valued attribute

insert
  $_ isa event-cadence P1M; # same local time on the same day of every month