Temporal.PlainTime

Table of Contents

A Temporal.PlainTime represents a wall-clock time, with a precision in nanoseconds, and without any time zone. "Wall-clock time" refers to the concept of a time as expressed in everyday usage — the time that you read off the clock on the wall. For example, it could be used to represent an event that happens daily at a certain time, no matter what time zone.

Temporal.PlainTime refers to a time with no associated calendar date; if you need to refer to a specific time on a specific day, use Temporal.PlainDateTime. A Temporal.PlainTime can be converted into a Temporal.ZonedDateTime by combining it with a Temporal.PlainDate and Temporal.TimeZone using the toZonedDateTime() method. It can also be combined with a Temporal.PlainDate to yield a "zoneless" Temporal.PlainDateTime using the toPlainDateTime() method.

Constructor

new Temporal.PlainTime(isoHour: number = 0, isoMinute: number = 0, isoSecond: number = 0, isoMillisecond: number = 0, isoMicrosecond: number = 0, isoNanosecond: number = 0) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object.

Use this constructor if you have the correct parameters for the time already as individual number values in the ISO 8601 calendar. Otherwise, Temporal.PlainTime.from(), which accepts more kinds of input and allows controlling the overflow behavior, is probably more convenient.

All values are given as reckoned in the ISO 8601 calendar.

Usage examples:

// Leet hour
time = new Temporal.PlainTime(13, 37); // => 13:37:00

Static methods

Temporal.PlainTime.from(thing: any, options?: object) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object.

This static method creates a new Temporal.PlainTime object from another value. If the value is another Temporal.PlainTime object, a new object representing the same time is returned. If the value is any other object, a Temporal.PlainTime will be constructed from the values of any hour, minute, second, millisecond, microsecond, and nanosecond properties that are present. Any missing ones will be assumed to be 0.

If the calendar property is present, it must be the string 'iso8601' or the ISO 8601 calendar, for future compatibility.

Any non-object value will be converted to a string, which is expected to be in ISO 8601 format. If the string designates a date, it will be ignored. Time zone or UTC offset information will also be ignored, with one exception: if a string contains a Z in place of a numeric UTC offset, then a RangeError will be thrown because interpreting these strings as a local time is usually a bug. Temporal.Instant.from should be used instead to parse these strings, and the result's toZonedDateTimeISO method can be used to obtain a timezone-local date and time.

In unusual cases of needing date or time components of Z-terminated timestamp strings (e.g. daily rollover of a UTC-timestamped log file), use the time zone 'UTC'. For example, the following code returns a "UTC time": Temporal.Instant.from(thing).toZonedDateTimeISO('UTC').toPlainTime().

The overflow option works as follows, if thing is an object:

The overflow option is ignored if thing is a string.

NOTE: Although Temporal does not deal with leap seconds, times coming from other software may have a second value of 60. In the default constrain mode, this will be converted to 59. In reject mode, the constructor will throw, so if you have to interoperate with times that may contain leap seconds, don't use reject. However, if parsing an ISO 8601 string with a seconds component of :60, then it will always result in a second value of 59, in accordance with POSIX.

Example usage:

time = Temporal.PlainTime.from('03:24:30'); // => 03:24:30
time = Temporal.PlainTime.from('032430'); // => 03:24:30
time = Temporal.PlainTime.from('1995-12-07T03:24:30'); // => 03:24:30
time = Temporal.PlainTime.from('1995-12-07T03:24:30+01:00[Europe/Brussels]');
  // => 03:24:30
  // (same as above; time zone is ignored)
time === Temporal.PlainTime.from(time); // => false

time = Temporal.PlainTime.from({
  hour: 19,
  minute: 39,
  second: 9,
  millisecond: 68,
  microsecond: 346,
  nanosecond: 205
}); // => 19:39:09.068346205
time = Temporal.PlainTime.from({ hour: 19, minute: 39, second: 9 }); // => 19:39:09
time = Temporal.PlainTime.from(Temporal.PlainDateTime.from('2020-02-15T19:39:09'));
  // => 19:39:09
  // (same as above; Temporal.PlainDateTime has hour, minute, etc. properties)

// Different overflow modes
time = Temporal.PlainTime.from({ hour: 15, minute: 60 }, { overflow: 'constrain' });
  // => 15:59:00
time = Temporal.PlainTime.from({ hour: 15, minute: -1 }, { overflow: 'constrain' });
  // => 15:00:00
time = Temporal.PlainTime.from({ hour: 15, minute: 60 }, { overflow: 'reject' });
  // => throws
time = Temporal.PlainTime.from({ hour: 15, minute: -1 }, { overflow: 'reject' });
  // => throws

Temporal.PlainTime.compare(one: Temporal.PlainTime | object | string, two: Temporal.PlainTime | object | string) : number

Parameters:

Returns: −1, 0, or 1.

Compares two Temporal.PlainTime objects. Returns an integer indicating whether one comes before or after or is equal to two.

If one and two are not Temporal.PlainTime objects, then they will be converted to one as if they were passed to Temporal.PlainTime.from().

This function can be used to sort arrays of Temporal.PlainTime objects. For example:

one = Temporal.PlainTime.from('03:24');
two = Temporal.PlainTime.from('01:24');
three = Temporal.PlainTime.from('01:24:05');
sorted = [one, two, three].sort(Temporal.PlainTime.compare);
sorted.join(' '); // => '01:24:00 01:24:05 03:24:00'

Note that time zone offset transitions (like when Daylight Saving Time starts or ends ends) can produce unexpected results when comparing times, because clock times can be skipped or repeated. Therefore, Temporal.ZonedDateTime.compare (not Temporal.PlainTime.compare) should be used if the caller's actual intent is to compare specific instants, e.g. arrivals of two airplane flights. For example:

// Backward transitions will repeat clock times
zdtDst = Temporal.ZonedDateTime.from('2020-11-01T01:45-07:00[America/Los_Angeles]');
zdtStandard = Temporal.ZonedDateTime.from('2020-11-01T01:30-08:00[America/Los_Angeles]');
// The "first" 1:45 (in Daylight Time) is earlier than the "second" 1:30 (in Standard Time)
Temporal.ZonedDateTime.compare(zdtDst, zdtStandard); // => -1
// 1:45 is later than 1:30 when looking at a wall clock
Temporal.PlainTime.compare(zdtDst, zdtStandard); // => 1

// Forward transitions will skip clock times. Skipped times will be disambiguated.
zdtBase = Temporal.ZonedDateTime.from('2020-03-08[America/Los_Angeles]');
timeSkipped = Temporal.PlainTime.from('02:30');
timeValid = Temporal.PlainTime.from('03:30');
zdtSkipped = zdtBase.withPlainTime(timeSkipped);
zdtValid = zdtBase.withPlainTime(timeValid);
// The skipped time 2:30AM is disambiguated to 3:30AM, so the instants are equal
Temporal.ZonedDateTime.compare(zdtSkipped, zdtValid); // => 0
// 2:30 is earlier than 3:30 on a wall clock
Temporal.PlainTime.compare(timeSkipped, timeValid); // => -1

Properties

time.hour: number

time.minute: number

time.second: number

time.millisecond: number

time.microsecond: number

time.nanosecond: number

The above read-only properties allow accessing each component of the time individually.

Usage examples:

time = Temporal.PlainTime.from('19:39:09.068346205');
time.hour;        // => 19
time.minute;      // => 39
time.second;      // => 9
time.millisecond; // => 68
time.microsecond; // => 346
time.nanosecond;  // => 205

Methods

time.with(timeLike: object, options?: object) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object.

This method creates a new Temporal.PlainTime which is a copy of time, but any properties present on timeLike override the ones already present on time.

Since Temporal.PlainTime objects each represent a fixed time, use this method instead of modifying one.

NOTE: calendar and timeZone properties are not allowed on timeLike. See the toPlainDateTime and toZonedDateTime methods instead.

Usage example:

time = Temporal.PlainTime.from('19:39:09.068346205');
// What's the top of the next hour?
time.add({ hours: 1 }).with({
  minute: 0,
  second: 0,
  millisecond: 0,
  microsecond: 0,
  nanosecond: 0
}); // => 20:00:00

time.add(duration: Temporal.Duration | object | string) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object which is the time indicated by time plus duration.

This method adds duration to time. Due to times wrapping around when reaching 24 hours, the returned point in time may be either in the future or in the past relative to time, or even the same time.

The duration argument is an object with properties denoting a duration, such as { hours: 5, minutes: 30 }, or a string such as PT5H30M, or a Temporal.Duration object. If duration is not a Temporal.Duration object, then it will be converted to one as if it were passed to Temporal.Duration.from().

Adding a negative duration is equivalent to subtracting the absolute value of that duration.

Usage example:

time = Temporal.PlainTime.from('19:39:09.068346205');
time.add({ minutes: 5, nanoseconds: 800 }); // => 19:44:09.068347005

time.subtract(duration: Temporal.Duration | object | string) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object which is the time indicated by time minus duration.

This method subtracts duration from time. Due to times wrapping around when reaching 24 hours, the returned point in time may be either in the future or in the past relative to time, or even the same time.

The duration argument is an object with properties denoting a duration, such as { hours: 5, minutes: 30 }, or a string such as PT5H30M, or a Temporal.Duration object. If duration is not a Temporal.Duration object, then it will be converted to one as if it were passed to Temporal.Duration.from().

Subtracting a negative duration is equivalent to adding the absolute value of that duration.

Usage example:

time = Temporal.PlainTime.from('19:39:09.068346205');
time.subtract({ minutes: 5, nanoseconds: 800 }); // => 19:34:09.068345405

time.until(other: Temporal.PlainTime | object | string, options?: object) : Temporal.Duration

Parameters:

Returns: a Temporal.Duration representing the elapsed time after time and until other.

This method computes the difference between the two times represented by time and other, optionally rounds it, and returns it as a Temporal.Duration object. If other is earlier than time then the resulting duration will be negative. If using the default options, adding the returned Temporal.Duration to time will yield other.

If other is not a Temporal.PlainTime object, then it will be converted to one as if it were passed to Temporal.PlainTime.from().

The largestUnit parameter controls how the resulting duration is expressed. The returned Temporal.Duration object will not have any nonzero fields that are larger than the unit in largestUnit. A difference of two hours will become 7200 seconds when largestUnit is 'second', for example. However, a difference of 30 seconds will still be 30 seconds even if largestUnit is 'hour'. A value of 'auto' means 'hour'.

You can round the result using the smallestUnit, roundingIncrement, and roundingMode options. These behave as in the Temporal.Duration.round() method. The default is to do no rounding.

Usage example:

time = Temporal.PlainTime.from('20:13:20.971398099');
time.until(Temporal.PlainTime.from('22:39:09.068346205')); // => PT2H25M48.096948106S
time.until(Temporal.PlainTime.from('19:39:09.068346205')); // => -PT34M11.903051894S

// Rounding, for example if you don't care about sub-seconds
time.until(Temporal.PlainTime.from('22:39:09.068346205'), { smallestUnit: 'second' });
  // => PT2H25M48S

time.since(other: Temporal.PlainTime | object | string, options?: object) : Temporal.Duration

Parameters:

Returns: a Temporal.Duration representing the elapsed time before time and since other.

This method computes the difference between the two times represented by time and other, optionally rounds it, and returns it as a Temporal.Duration object. If other is later than time then the resulting duration will be negative.

This method is similar to Temporal.PlainTime.prototype.until(), but reversed. If using the default options, subtracting the returned Temporal.Duration from time will yield other, and time1.since(time2) will yield the same result as time1.until(time2).negated().

Usage example:

time = Temporal.PlainTime.from('20:13:20.971398099');
time.since(Temporal.PlainTime.from('19:39:09.068346205')); // => PT34M11.903051894S
time.since(Temporal.PlainTime.from('22:39:09.068346205')); // => -PT2H25M48.096948106S

time.round(roundTo: string | object) : Temporal.PlainTime

Parameters:

Returns: a new Temporal.PlainTime object which is time rounded to roundTo (if a string parameter is used) or roundingIncrement of smallestUnit (if an object parameter is used).

Rounds time to the given unit and increment, and returns the result as a new Temporal.PlainTime object.

The smallestUnit option (or the value of roundTo if a string parameter is used) determines the unit to round to. For example, to round to the nearest minute, use smallestUnit: 'minute'. This option is required.

The roundingIncrement option allows rounding to an integer number of units. For example, to round to increments of a half hour, use smallestUnit: 'minute', roundingIncrement: 30.

The value given as roundingIncrement must divide evenly into the next highest unit after smallestUnit, and must not be equal to it. (For example, if smallestUnit is 'minute', then the number of minutes given by roundingIncrement must divide evenly into 60 minutes, which is one hour. The valid values in this case are 1 (default), 2, 3, 4, 5, 6, 10, 12, 15, 20, and 30. Instead of 60 minutes, use 1 hour.)

The roundingMode option controls how the rounding is performed.

Several pairs of modes behave the same as each other, but are both included for consistency with Temporal.Duration.round(), where they are not the same.

The default rounding mode is 'halfExpand' to match how rounding is often taught in school. Note that this is different than the 'trunc' default used by until and since options because rounding up would be an unexpected default for those operations. Other properties behave identically between these methods.

Example usage:

time = Temporal.PlainTime.from('19:39:09.068346205');

// Round to a particular unit
time.round({ smallestUnit: 'hour' }); // => 20:00:00
// Round to an increment of a unit, e.g. half an hour:
time.round({ roundingIncrement: 30, smallestUnit: 'minute' });
  // => 19:30:00
// Round to the same increment but round up instead:
time.round({ roundingIncrement: 30, smallestUnit: 'minute', roundingMode: 'ceil' });
  // => 20:00:00

time.equals(other: Temporal.PlainTime | object | string) : boolean

Parameters:

Returns: true if time and other are equal, or false if not.

Compares two Temporal.PlainTime objects for equality.

This function exists because it's not possible to compare using time == other or time === other, due to ambiguity in the primitive representation and between Temporal types.

If you don't need to know the order in which the two times occur, then this function may be less typing and more efficient than Temporal.PlainTime.compare.

If other is not a Temporal.PlainTime object, then it will be converted to one as if it were passed to Temporal.PlainTime.from().

Example usage:

time = Temporal.PlainTime.from('19:39:09.068346205');
other = Temporal.PlainTime.from('20:13:20.971398099');
time.equals(other); // => false
time.equals(time); // => true

time.toString(options?: object) : string

Parameters:

Returns: a string in the ISO 8601 time format representing time.

This method overrides the Object.prototype.toString() method and provides a convenient, unambiguous string representation of time. The string can be passed to Temporal.PlainTime.from() to create a new Temporal.PlainTime object.

The output precision can be controlled with the fractionalSecondDigits or smallestUnit option. If no options are given, the default is fractionalSecondDigits: 'auto', which omits trailing zeroes after the decimal point.

The value is truncated to fit the requested precision, unless a different rounding mode is given with the roundingMode option, as in Temporal.PlainDateTime.round(). Note that rounding may change the value of other units as well.

Example usage:

time = Temporal.PlainTime.from('19:39:09.068346205');
time.toString(); // => '19:39:09.068346205'

time.toString({ smallestUnit: 'minute' }); // => '19:39'
time.toString({ fractionalSecondDigits: 0 }); // => '19:39:09'
time.toString({ fractionalSecondDigits: 4 }); // => '19:39:09.0683'
time.toString({ fractionalSecondDigits: 5, roundingMode: 'halfExpand' });
  // => '19:39:09.06835'

time.toLocaleString(locales?: string | array<string>, options?: object) : string

Parameters:

Returns: a language-sensitive representation of time.

This method overrides Object.prototype.toLocaleString() to provide a human-readable, language-sensitive representation of time.

The locales and options arguments are the same as in the constructor to Intl.DateTimeFormat.

NOTE: Unlike in Temporal.Instant.prototype.toLocaleString(), locales.timeZone will have no effect, because Temporal.PlainTime carries no time zone information and is just a wall-clock time.

Example usage:

time = Temporal.PlainTime.from('19:39:09.068346205');
time.toLocaleString(); // example output: '7:39:09 PM'
time.toLocaleString('de-DE'); // example output: '19:39:09'
time.toLocaleString('de-DE', { timeZone: 'Europe/Berlin' }); // => '19:39:09'
time.toLocaleString('en-US-u-nu-fullwide-hc-h24'); // => '19:39:09'

time.toJSON() : string

Returns: a string in the ISO 8601 date format representing time.

This method is the same as time.toString(). It is usually not called directly, but it can be called automatically by JSON.stringify().

The reverse operation, recovering a Temporal.PlainTime object from a string, is Temporal.PlainTime.from(), but it cannot be called automatically by JSON.parse(). If you need to rebuild a Temporal.PlainTime object from a JSON string, then you need to know the names of the keys that should be interpreted as Temporal.PlainTimes. In that case you can build a custom "reviver" function for your use case.

Example usage:

const workBreak = {
  type: 'mandatory',
  name: 'Lunch',
  startTime: Temporal.PlainTime.from({ hour: 12 }),
  endTime: Temporal.PlainTime.from({ hour: 13 })
};
const str = JSON.stringify(workBreak, null, 2);
console.log(str);
// =>
// {
//   "type": "mandatory",
//   "name": "Lunch",
//   "startTime": "12:00",
//   "endTime": "13:00"
// }

// To rebuild from the string:
function reviver(key, value) {
  if (key.endsWith('Time')) return Temporal.PlainTime.from(value);
  return value;
}
JSON.parse(str, reviver);

time.valueOf()

This method overrides Object.prototype.valueOf() and always throws an exception. This is because it's not possible to compare Temporal.PlainTime objects with the relational operators <, <=, >, or >=. Use Temporal.PlainTime.compare() for this, or time.equals() for equality.

time.toZonedDateTime(item: object) : Temporal.ZonedDateTime

Parameters:

Returns: a Temporal.ZonedDateTime object that represents the clock time on the calendar plainDate projected into timeZone.

This method can be used to convert Temporal.PlainTime into a Temporal.ZonedDateTime, by supplying the time zone and date.

For a list of IANA time zone names, see the current version of the IANA time zone database. A convenient list is also available on Wikipedia, although it might not reflect the latest official status.

In addition to the timeZone, the converted object carries a copy of all the relevant fields of time and plainDate. If plainDate is not a Temporal.PlainDate object, then it will be converted to one as if it were passed to Temporal.PlainDate.from(). This method produces identical results to Temporal.PlainDate.from(plainDate).toPlainDateTime(time).toZonedDateTime(timeZone).

In the case of ambiguity caused by DST or other time zone changes, the earlier time will be used for backward transitions and the later time for forward transitions. When interoperating with existing code or services, this matches the behavior of legacy Date as well as libraries like moment.js, Luxon, and date-fns. This mode also matches the behavior of cross-platform standards like RFC 5545 (iCalendar).

During "skipped" clock time like the hour after DST starts in the Spring, this method interprets invalid times using the pre-transition time zone offset. This behavior avoids exceptions when converting nonexistent date/time values to Temporal.ZonedDateTime, but it also means that values during these periods will result in a different Temporal.PlainTime value in "round-trip" conversions to Temporal.ZonedDateTime and back again.

For usage examples and a more complete explanation of how this disambiguation works, see Resolving ambiguity.

If the result is outside the range that Temporal.ZonedDateTime can represent (approximately half a million years centered on the Unix epoch), then a RangeError will be thrown.

Usage example:

plainTime = Temporal.PlainTime.from('15:23:30.003');
plainDate = Temporal.PlainDate.from('2006-08-24');
plainTime.toZonedDateTime({ timeZone: 'America/Los_Angeles', plainDate });
// => 2006-08-24T15:23:30.003-07:00[America/Los_Angeles]

time.toPlainDateTime(date: Temporal.PlainDate | object | string) : Temporal.PlainDateTime

Parameters:

Returns: a Temporal.PlainDateTime object that represents the wall-clock time time on the calendar date date.

This method can be used to convert Temporal.PlainTime into a Temporal.PlainDateTime, by supplying the calendar date to use. The converted object carries a copy of all the relevant fields of date and time.

This has identical results to Temporal.PlainDate.from(date).toPlainDateTime(time).

If date is not a Temporal.PlainDate object, then it will be converted to one as if it were passed to Temporal.PlainDate.from().

Usage example:

time = Temporal.PlainTime.from('15:23:30.003');
date = Temporal.PlainDate.from('2006-08-24');
time.toPlainDateTime(date); // => 2006-08-24T15:23:30.003

time.getISOFields(): { isoHour: number, isoMinute: number, isoSecond: number, isoMillisecond: number, isoMicrosecond: number, isoNanosecond: number }

Returns: a plain object with properties expressing time in the ISO 8601 calendar.

This method is present for forward compatibility with custom calendars.

Usage example:

time = Temporal.PlainTime.from('03:20:00');
f = time.getISOFields();
f.isoHour; // => 3