Temporal.Duration

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The Temporal.Duration object represents a difference between two time points, which can be used in date/time arithmetic. It is fundamentally represented as a combination of years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds values.

Description

ISO 8601 duration format

Duration objects can be serialized and parsed using the ISO 8601 duration format (with some extensions specified by ECMAScript). The string has the following form (spaces are only for readability and should not be present in the actual string):

±P nY nM nW nD T nH nM nS
± Optional

An optional sign character (+ or -), which represents positive or negative duration. Default is positive.

P

A literal character P or p that stands for "period".

nY, nM, nW, nD, nH, nM, nS

A number followed by a literal character, which represents the number of years (Y), months (M), weeks (W), days (D), hours (H), minutes (M), or seconds (S), respectively. All except the last existing component must be an integer. The last component, if it is a time component (hours, minutes, or seconds), may have a fractional part of 1 to 9 digits, led by a dot or a comma, such as PT0.0021S or PT1.1H. Any zero components may be omitted, but at least one component should be present (even if it has value zero, in which case the duration is zero).

T

A literal character T or t that separates the date part from the time part, which should be present if and only if there's at least one component after it.

Here are some examples:

ISO 8601 Meaning
P1Y1M1DT1H1M1.1S 1 year, 1 month, 1 day, 1 hour, 1 minute, 1 second, and 100 milliseconds
P40D 40 days
P1Y1D 1 year and 1 day
P3DT4H59M 3 days, 4 hours and 59 minutes
PT2H30M 2 hours and 30 minutes
P1M 1 month
PT1M 1 minute
PT0.0021S 2.1 milliseconds (2 milliseconds and 100 microseconds)
PT0S Zero (canonical representation)
P0D Zero

Note: According to the ISO 8601-1 standard, weeks are not allowed to appear together with any other units, and durations can only be positive. As extensions to the standard, ISO 8601-2, which Temporal uses, allows a sign character at the start of the string, and allows combining weeks with other units. Therefore, if your duration is serialized to a string like P3W1D, +P1M, or -P1M, note that other programs may not accept it.

When serializing, the output respects the stored components as much as possible, preserving unbalanced components. However, subsecond components are serialized as a single fractional second, so their precise values, if unbalanced may be lost. The plus sign is omitted for positive durations. The zero duration is always serialized as PT0S.

Calendar durations

A calendar duration is one that contains any of the calendar units: weeks, months, and years. A non-calendar duration is portable and can participate in date/time arithmetic without any calendar information, because they unambiguously represent a fixed amount of time. However, a calendar duration is not portable because the number of days in a month or year depends on the calendar system and the reference time point. Therefore, attempting to perform any arithmetic operation on a calendar durations throws an error because durations don't keep track of a calendar themselves. For example, if we are in May of the Gregorian calendar, then "1 month" is "31 days", but if we are in April, then "1 month" becomes "30 days". To add or subtract calendar durations, you need to add them to dates instead:

js
const dur1 = Temporal.Duration.from({ years: 1 });
const dur2 = Temporal.Duration.from({ months: 1 });

dur1.add(dur2); // RangeError: can't compare durations when "relativeTo" is undefined

const startingPoint = Temporal.PlainDate.from("2021-01-01"); // ISO 8601 calendar
startingPoint.add(dur1).add(dur2).since(startingPoint); // "P396D"

Other operations, including round(), total(), and compare(), take a relativeTo option to provide the necessary calendar and reference time information. This option can be a Temporal.PlainDate, Temporal.PlainDateTime, Temporal.ZonedDateTime, or otherwise an object or string that's convertible using Temporal.ZonedDateTime.from() (if the timeZone option is provided or the string contains time zone annotation) or Temporal.PlainDateTime.from().

Note that days to hours conversion is also technically ambiguous because the length of a day may vary due to offset changes, such as daylight saving time. You can provide a zoned relativeTo to account for these changes; otherwise 24-hour days are assumed.

Duration balancing

There are many ways to represent the same duration: for example, "1 minute and 30 seconds" and "90 seconds" are equivalent. However, depending on the context, one representation may be more appropriate than the other. Therefore, generally, the Duration object preserves the input values as much as possible, so that when you format it, it will be displayed as you expect.

Each component of a duration has its optimal range; hours should be from 0 to 23, minutes from 0 to 59, and so on. When a component overflows its optimal range, the excess may be "carried" into the next larger component. To carry over, we need to answer the question of "how many X are in a Y?", which is a complicated question for calendar units, so in this case a calendar is needed. Also note that by default, days are directly carried into months; the weeks unit is only carried into if explicitly requested. If we carry as much as possible, the eventual result where all components are within their optimal range is called a "balanced" duration. Unbalanced durations usually come in the "top-heavy" form, where the largest unit is unbalanced (e.g., "27 hours and 30 minutes"); other forms, such as "23 hours and 270 minutes", are rarely seen.

The round() method always balances the duration into the "top-heavy" form, up to the largestUnit option. With a manual largestUnit option that's large enough, you can fully balance the duration. Similarly, the add() and subtract() methods balance the result duration to the largest unit of the input durations.

Note that because the ISO 8601 duration format represents subsecond components as one single fraction number, it is not possible to preserve unbalanced subsecond components during serialization using the default format. For example, "1000 milliseconds" is serialized as "PT1S", and then deserialized as "1 second". If you need to preserve the subsecond components' magnitudes, you need to manually serialize it as a JSON object instead (because by default the toJSON() method serializes the duration in the ISO 8601 format).

Duration sign

Because a duration is a difference between two time points, it can be positive, negative, or zero. For example, if you are displaying event times in relative time, then negative durations may represent events in the past, and positive durations for the future. In our representation using a combination of time components, the sign is stored within each component: a negative duration always has all components negative (or zero), and a positive duration always has all components positive (or zero). Constructing a duration with components of mixed signs is invalid and will be rejected by the constructor or the with() method. The add() and subtract() methods will balance the result duration to avoid mixed signs.

Constructor

Temporal.Duration() Experimental

Creates a new Temporal.Duration object by directly supplying the underlying data.

Static methods

Temporal.Duration.compare() Experimental

Returns a number (-1, 0, or 1) indicating whether the first duration is shorter, equal to, or longer than the second duration.

Temporal.Duration.from() Experimental

Creates a new Temporal.Duration object from another Temporal.Duration object, an object with duration properties, or an ISO 8601 string.

Instance properties

These properties are defined on Temporal.Duration.prototype and shared by all Temporal.Duration instances.

Temporal.Duration.prototype.blank Experimental

Returns a boolean that is true if this duration represents a zero duration, and false otherwise. Equivalent to duration.sign === 0.

Temporal.Duration.prototype.constructor

The constructor function that created the instance object. For Temporal.Duration instances, the initial value is the Temporal.Duration() constructor.

Temporal.Duration.prototype.days Experimental

Returns an integer representing the number of days in the duration.

Temporal.Duration.prototype.hours Experimental

Returns an integer representing the number of hours in the duration.

Temporal.Duration.prototype.microseconds Experimental

Returns an integer representing the number of microseconds in the duration.

Temporal.Duration.prototype.milliseconds Experimental

Returns an integer representing the number of milliseconds in the duration.

Temporal.Duration.prototype.minutes Experimental

Returns an integer representing the number of minutes in the duration.

Temporal.Duration.prototype.months Experimental

Returns an integer representing the number of months in the duration.

Temporal.Duration.prototype.nanoseconds Experimental

Returns an integer representing the number of nanoseconds in the duration.

Temporal.Duration.prototype.seconds Experimental

Returns an integer representing the number of seconds in the duration.

Temporal.Duration.prototype.sign Experimental

Returns 1 if this duration is positive, -1 if negative, and 0 if zero.

Temporal.Duration.prototype.weeks Experimental

Returns an integer representing the number of weeks in the duration.

Temporal.Duration.prototype.years Experimental

Returns an integer representing the number of years in the duration.

Temporal.Duration.prototype[Symbol.toStringTag]

The initial value of the [Symbol.toStringTag] property is the string "Temporal.Duration". This property is used in Object.prototype.toString().

Instance methods

Temporal.Duration.prototype.abs() Experimental

Returns a new Temporal.Duration object with the absolute value of this duration (all fields keep the same magnitude, but sign becomes positive).

Temporal.Duration.prototype.add() Experimental

Returns a new Temporal.Duration object with the sum of this duration and a given duration (in a form convertible by Temporal.Duration.from()). The result is balanced.

Temporal.Duration.prototype.negated() Experimental

Returns a new Temporal.Duration object with the negated value of this duration (all fields keep the same magnitude, but sign becomes reversed).

Temporal.Duration.prototype.round() Experimental

Returns a new Temporal.Duration object with the duration rounded to the given smallest unit and/or balanced to the given largest unit.

Temporal.Duration.prototype.subtract() Experimental

Returns a new Temporal.Duration object with the difference between this duration and a given duration (in a form convertible by Temporal.Duration.from()). Equivalent to adding the negated value of the other duration.

Temporal.Duration.prototype.toJSON() Experimental

Returns a string representing this duration in the same ISO 8601 format as calling toString(). Intended to be implicitly called by JSON.stringify().

Temporal.Duration.prototype.toLocaleString() Experimental

Returns a string with a language-sensitive representation of this duration. In implementations with Intl.DurationFormat API support, this method delegates to Intl.DurationFormat.

Temporal.Duration.prototype.toString() Experimental

Returns a string representing this duration in the ISO 8601 format.

Temporal.Duration.prototype.total() Experimental

Returns a number representing the total duration in the given unit.

Temporal.Duration.prototype.valueOf() Experimental

Throws a TypeError, which prevents Temporal.Duration instances from being implicitly converted to primitives when used in arithmetic or comparison operations.

Temporal.Duration.prototype.with() Experimental

Returns a new Temporal.Duration object representing this duration with some fields replaced by new values.

Specifications

Specification
Temporal proposal
# sec-temporal-duration-objects

Browser compatibility

BCD tables only load in the browser

See also