Temporal.PlainDateTime

Table of Contents

A Temporal.PlainDateTime represents a calendar date and wall-clock time, with a precision in nanoseconds, and without any time zone.

For use cases that require a time zone, especially using arithmetic or other derived values, consider using Temporal.ZonedDateTime instead because that type automatically adjusts for Daylight Saving Time. A Temporal.PlainDateTime can be converted to a Temporal.ZonedDateTime using a Temporal.TimeZone.

Temporal.PlainDate, Temporal.PlainTime, Temporal.PlainYearMonth, and Temporal.PlainMonthDay all carry less information and should be used when complete information is not required.

A Temporal.PlainDateTime can be converted into any of the types mentioned above using conversion methods like toZonedDateTime or toPlainDate.

Because Temporal.PlainDateTime does not represent an exact point in time, most date/time use cases are better handled using exact time types like Temporal.ZonedDateTime and Temporal.Instant. But there are cases where Temporal.PlainDateTime is the correct type to use:

To learn more about time zones and DST best practices, visit Time Zones and Resolving Ambiguity.

Constructor

new Temporal.PlainDateTime(isoYear: number, isoMonth: number, isoDay: number, isoHour: number = 0, isoMinute: number = 0, isoSecond: number = 0, isoMillisecond: number = 0, isoMicrosecond: number = 0, isoNanosecond: number = 0, calendar: string | object = "iso8601") : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object.

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

All values are given as reckoned in the ISO 8601 calendar. Together, isoYear, isoMonth, and isoDay must represent a valid date in that calendar, even if you are passing a different calendar as the calendar parameter, and the time parameters must represent a valid time of day.

NOTE: Although Temporal does not deal with leap seconds, dates coming from other software may have a second value of 60. This value will cause the constructor will throw, so if you have to interoperate with times that may contain leap seconds, use Temporal.PlainDateTime.from() instead.

The range of allowed values for this type is wider (by one nanosecond smaller than one day) on each end than the range of Temporal.Instant. Because the magnitude of built-in time zones' UTC offset will always be less than 24 hours, this extra range ensures that a valid Temporal.Instant can always be converted to a valid Temporal.PlainDateTime using any built-in time zone. Note that the reverse conversion is not guaranteed to succeed; a valid Temporal.PlainDateTime at the edge of its range may, for some built-in time zones, be out of range of Temporal.Instant. If the parameters passed in to this constructor are out of range, then this function will throw a RangeError.

Usually calendar will be a string containing the identifier of a built-in calendar, such as 'islamic' or 'gregory'. Use an object if you need to supply custom calendar behaviour.

NOTE: The isoMonth argument ranges from 1 to 12, which is different from legacy Date where months are represented by zero-based indices (0 to 11).

Usage examples:

// Leet hour on pi day in 2020
datetime = new Temporal.PlainDateTime(2020, 3, 14, 13, 37); // => 2020-03-14T13:37:00

Static methods

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

Parameters:

Returns: a new Temporal.PlainDateTime object.

This static method creates a new Temporal.PlainDateTime object from another value. If the value is another Temporal.PlainDateTime object, a new object representing the same date and time is returned. If the value is any other object, a Temporal.PlainDateTime will be constructed from the values of any year (or era and eraYear), month (or monthCode), day, hour, minute, second, millisecond, microsecond, nanosecond, and calendar properties that are present.

At least the year (or era and eraYear), month (or monthCode), and day properties must be present. Default values for other missing fields are determined by the calendar.

If the calendar property is not present, it's assumed to be 'iso8601' (identifying the ISO 8601 calendar). Any other missing properties will be assumed to be 0 (for time fields).

Any non-object value is converted to a string, which is expected to be in ISO 8601 format. Time zone or UTC offset information will 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 date and 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 date": Temporal.Instant.from(thing).toZonedDateTimeISO('UTC').toPlainDate().

If the string isn't valid according to ISO 8601, then a RangeError will be thrown regardless of the value of overflow.

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

The overflow option is ignored if thing is a string.

Additionally, if the result is earlier or later than the range of dates that Temporal.PlainDateTime can represent (approximately half a million years centered on the Unix epoch), then this method will throw a RangeError regardless of overflow.

NOTE: Although Temporal does not deal with leap seconds, dates coming from other software may have a second value of 60. In the default constrain mode and when parsing an ISO 8601 string, this will be converted to 59. In reject mode, this function will throw, so if you have to interoperate with times that may contain leap seconds, don't use reject.

NOTE: The allowed values for the thing.month property start at 1, which is different from legacy Date where months are represented by zero-based indices (0 to 11).

Example usage:

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

dt = Temporal.PlainDateTime.from({
  year: 1995,
  month: 12,
  day: 7,
  hour: 3,
  minute: 24,
  second: 30,
  millisecond: 0,
  microsecond: 3,
  nanosecond: 500
}); // => 1995-12-07T03:24:30.0000035
dt = Temporal.PlainDateTime.from({ year: 1995, month: 12, day: 7 }); // => 1995-12-07T00:00:00
dt = Temporal.PlainDateTime.from(Temporal.PlainDate.from('1995-12-07T03:24:30'));
  // => 1995-12-07T00:00:00
  // same as above; Temporal.PlainDate has year, month, and day properties

dt = Temporal.PlainDateTime.from({ year: 5756, month: 3, day: 14, hour: 3, minute: 24, second: 30, calendar: 'hebrew' });
  // => 1995-12-07T03:24:30[u-ca=hebrew]

// Different overflow modes
dt = Temporal.PlainDateTime.from({ year: 2001, month: 13, day: 1 }, { overflow: 'constrain' });
  // => 2001-12-01T00:00:00
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 32 }, { overflow: 'constrain' });
  // => 2001-01-31T00:00:00
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 1, hour: 25 }, { overflow: 'constrain' });
  // => 2001-01-01T23:00:00
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 1, minute: 60 }, { overflow: 'constrain' });
  // => 2001-01-01T00:59:00
dt = Temporal.PlainDateTime.from({ year: 2001, month: 13, day: 1 }, { overflow: 'reject' });
  // => throws
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 32 }, { overflow: 'reject' });
  // => throws
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 1, hour: 25 }, { overflow: 'reject' });
  // => throws
dt = Temporal.PlainDateTime.from({ year: 2001, month: 1, day: 1, minute: 60 }, { overflow: 'reject' });
  // => throws

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

Parameters:

Returns: −1, 0, or 1.

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

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

Calendars are ignored in the comparison. For example, this method returns 0 for instances that fall on the same day and time in the ISO 8601 calendar, even if their calendars describe it with a different year, month, and/or day.

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

one = Temporal.PlainDateTime.from('1995-12-07T03:24');
two = Temporal.PlainDateTime.from('1995-12-07T01:24');
three = Temporal.PlainDateTime.from('2015-12-07T01:24');
sorted = [one, two, three].sort(Temporal.PlainDateTime.compare);
sorted.join(' ');
// => '1995-12-07T01:24:00 1995-12-07T03:24:00 2015-12-07T01:24:00'

Properties

datetime.year : number

datetime.month : number

datetime.monthCode : string

datetime.day : number

datetime.hour: number

datetime.minute: number

datetime.second: number

datetime.millisecond: number

datetime.microsecond: number

datetime.nanosecond: number

The above read-only properties allow accessing each component of a date or time individually.

Date unit details:

Either month or monthCode can be used in from or with to refer to the month. Similarly, in calendars that user eras an era/eraYear pair can be used in place of year when calling from or with.

Time unit details:

Usage examples:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.year;        // => 1995
dt.month;       // => 12
dt.monthCode;   // => 'M12'
dt.day;         // => 7
dt.hour;        // => 3
dt.minute;      // => 24
dt.second;      // => 30
dt.millisecond; // => 0
dt.microsecond; // => 3
dt.nanosecond;  // => 500

dt = Temporal.PlainDateTime.from('2019-02-23T03:24:30.000003500[u-ca=hebrew]');
dt.year;        // => 5779
dt.month;       // => 6
dt.monthCode;   // => 'M05L'
dt.day;         // => 18
dt.hour;        // => 3
dt.minute;      // => 24
dt.second;      // => 30
dt.millisecond; // => 0
dt.microsecond; // => 3
dt.nanosecond;  // => 500

datetime.calendarId : string

The calendarId read-only property gives the identifier of the calendar that the year, month, monthCode, and day properties are interpreted in. If the date was created with a custom calendar object, this gives the id property of that object.

datetime.era : string | undefined

datetime.eraYear : number | undefined

In calendars that use eras, the era and eraYear read-only properties can be used together to resolve an era-relative year. Both properties are undefined when using the ISO 8601 calendar. As inputs to from or with, era and eraYear can be used instead of year. Unlike year, eraYear may decrease as time proceeds because some eras (like the BCE era in the Gregorian calendar) count years backwards.

date = Temporal.PlainDateTime.from('-000015-01-01T12:30[u-ca=gregory]');
date.era;
// => 'bce'
date.eraYear;
// => 16
date.year;
// => -15

datetime.dayOfWeek : number

The dayOfWeek read-only property gives the weekday number that the date falls on. For the ISO 8601 calendar, the weekday number is defined as in the ISO 8601 standard: a value between 1 and 7, inclusive, with Monday being 1, and Sunday 7. For an overview, see ISO 8601 on Wikipedia.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'][dt.dayOfWeek - 1]; // => 'THU'

datetime.dayOfYear : number

The dayOfYear read-only property gives the ordinal day of the year that the date falls on. For the ISO 8601 calendar, this is a value between 1 and 365, or 366 in a leap year.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
// ISO ordinal date
console.log(dt.year, dt.dayOfYear); // => '1995 341'

datetime.weekOfYear : number

The weekOfYear read-only property gives the ISO week number of the date. For the ISO 8601 calendar, this is normally a value between 1 and 52, but in a few cases it can be 53 as well. ISO week 1 is the week containing the first Thursday of the year. For more information on ISO week numbers, see for example the Wikipedia article on ISO week date.

When combining the week number with a year number, make sure to use datetime.yearOfWeek instead of datetime.year. This is because the first few days of a calendar year may be part of the last week of the previous year, and the last few days of a calendar year may be part of the first week of the new year, depending on which year the first Thursday falls in.

Usage example:

dt = Temporal.PlainDateTime.from('2022-01-01T03:24:30.000003500');
// ISO week date
console.log(dt.yearOfWeek, dt.weekOfYear, dt.dayOfWeek); // => '2021 52 6'

datetime.yearOfWeek : number

The yearOfWeek read-only property gives the ISO "week calendar year" of the date, which is the year number corresponding to the ISO week number. For the ISO 8601 calendar, this is normally the same as datetime.year, but in a few cases it may be the previous or following year. For more information on ISO week numbers, see for example the Wikipedia article on ISO week date.

See weekOfYear for a usage example.

datetime.daysInWeek : number

The daysInWeek read-only property gives the number of days in the week that the date falls in. For the ISO 8601 calendar, this is always 7, but in other calendar systems it may differ from week to week.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.daysInWeek; // => 7

datetime.daysInMonth : number

The daysInMonth read-only property gives the number of days in the month that the date falls in. For the ISO 8601 calendar, this is 28, 29, 30, or 31, depending on the month and whether the year is a leap year.

Usage example:

// Attempt to write some mnemonic poetry
const monthsByDays = {};
for (let month = 1; month <= 12; month++) {
  const dt = Temporal.Now.plainDateTimeISO().with({ month });
  monthsByDays[dt.daysInMonth] = (monthsByDays[dt.daysInMonth] || []).concat(dt);
}

const strings = monthsByDays[30].map((dt) => dt.toLocaleString('en', { month: 'long' }));
// Shuffle to improve poem as determined empirically
strings.unshift(strings.pop());
const format = new Intl.ListFormat('en');
const poem = `Thirty days hath ${format.format(strings)}`;

console.log(poem);

datetime.daysInYear : number

The daysInYear read-only property gives the number of days in the year that the date falls in. For the ISO 8601 calendar, this is 365 or 366, depending on whether the year is a leap year.

Usage example:

dt = Temporal.Now.plainDateTimeISO();
percent = dt.dayOfYear / dt.daysInYear;
`The year is ${percent.toLocaleString('en', { style: 'percent' })} over!`;
// example output: "The year is 10% over!"

datetime.monthsInYear: number

The monthsInYear read-only property gives the number of months in the year that the date falls in. For the ISO 8601 calendar, this is always 12, but in other calendar systems it may differ from year to year.

Usage example:

dt = Temporal.PlainDate.from('1900-01-01T12:00');
dt.monthsInYear; // => 12

datetime.inLeapYear : boolean

The inLeapYear read-only property tells whether the year that the date falls in is a leap year or not. Its value is true if the year is a leap year, and false if not.

NOTE: A "leap year" is a year that contains more days than other years (for solar or lunar calendars) or more months than other years (for lunisolar calendars like Hebrew or Chinese). In the ISO 8601 calendar, a year is a leap year (and has exactly one extra day, February 29) if it is evenly divisible by 4 but not 100 or if it is evenly divisible by 400.

Usage example:

// Is this year a leap year?
dt = Temporal.Now.plainDateTime('iso8601');
dt.inLeapYear; // example output: true
// Is 2100 a leap year? (no, because it's divisible by 100 and not 400)
dt.with({ year: 2100 }).inLeapYear; // => false

Methods

datetime.with(dateTimeLike: object, options?: object) : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object.

This method creates a new Temporal.PlainDateTime which is a copy of datetime, but any properties present on dateTimeLike override the ones already present on datetime.

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

If the result is earlier or later than the range of dates that Temporal.PlainDateTime can represent (approximately half a million years centered on the Unix epoch), then this method will throw a RangeError regardless of overflow.

NOTE: The allowed values for the dateTimeLike.month property start at 1, which is different from legacy Date where months are represented by zero-based indices (0 to 11).

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

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.with({ year: 2015, second: 31 }); // => 2015-12-07T03:24:31.0000035

datetime.withPlainTime(plainTime?: object | string) : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object which is the date indicated by datetime, combined with the time represented by plainTime.

Valid input to withPlainTime is the same as valid input to Temporal.PlainTime.from, including strings like 12:15:36, plain object property bags like { hour: 20, minute: 30 }, or Temporal objects that contain time fields: Temporal.PlainTime, Temporal.ZonedDateTime, or Temporal.PlainDateTime.

This method is similar to with, but with a few important differences:

If plainTime is a Temporal.PlainTime object, then this method returns the same result as plainTime.toPlainDateTime(datetime) but can be easier to use, especially when chained to previous operations that return a Temporal.PlainDateTime.

Usage example:

dt = Temporal.PlainDateTime.from('2015-12-07T03:24:30.000003500');
dt.withPlainTime({ hour: 10 }); // => 2015-12-07T10:00:00
time = Temporal.PlainTime.from('11:22');
dt.withPlainTime(time); // => 2015-12-07T11:22:00
dt.withPlainTime('12:34'); // => 2015-12-07T12:34:00

// easier for chaining
dt.add({ days: 2, hours: 22 }).withPlainTime('00:00'); // => 2015-12-10T00:00:00

datetime.withPlainDate(plainDate: object | string) : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object which is the date indicated by datetime, combined with the date represented by plainDate.

Valid input to withPlainDate is the same as valid input to Temporal.PlainDate.from, including strings like 2000-03-01, plain object property bags like { year: 2020, month: 3, day: 1 }, or Temporal objects that contain a year, month, and day property, including Temporal.PlainDate, Temporal.PlainDateTime, or Temporal.ZonedDateTime.

All three date units (year, month, and day) are required. Temporal.YearMonth and Temporal.MonthDay are not valid input because they lack all date units. Both of those types have a toPlainDate method that can be used to obtain a Temporal.PlainDate which can in turn be used as input to withPlainDate.

If plainDate contains a non-ISO 8601 calendar, then the result of withPlainDate will be the calendar of plainDate. However, if datetime.calendar is already a non-ISO 8601 calendar, then this method will throw a RangeError. To resolve the error, first convert one of the instances to the same calendar or the ISO 8601 calendar, e.g. using .withCalendar('iso8601').

This method is similar to with, but with a few important differences:

If plainDate is a Temporal.PlainDate object, then this method returns the same result as plainDate.toPlainDateTime(datetime) but can be easier to use, especially when chained to previous operations that return a Temporal.PlainDateTime.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30');
dt.withPlainDate({ year: 2000, month: 6, day: 1 }); // => 2000-06-01T03:24:30
date = Temporal.PlainDate.from('2020-01-23');
dt.withPlainDate(date); // => 2020-01-23T03:24:30
dt.withPlainDate('2018-09-15'); // => 2018-09-15T03:24:30

// easier for chaining
dt.add({ hours: 12 }).withPlainDate('2000-06-01'); // => 2000-06-01T15:24:30

// result contains a non-ISO calendar if present in the input
dt.withCalendar('japanese').withPlainDate('2008-09-06'); // => 2008-09-06T03:24:30[u-ca=japanese]
dt.withPlainDate('2017-09-06[u-ca=japanese]'); // => 2017-09-06T03:24:30[u-ca=japanese]
/* WRONG */ dt.withCalendar('japanese').withPlainDate('2017-09-06[u-ca=hebrew]'); // => RangeError (calendar conflict)

datetime.withCalendar(calendar: object | string) : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object which is the date indicated by datetime, projected into calendar.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500[u-ca=japanese]');
dt.withCalendar('iso8601'); // => 1995-12-07T03:24:30.0000035

datetime.add(duration: Temporal.Duration | object | string, options?: object) : Temporal.PlainDateTime

Parameters:

Returns: a new Temporal.PlainDateTime object which is the date and time indicated by datetime plus duration.

This method adds duration to datetime, returning a point in time that is in the future relative to datetime.

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().

Some additions may be ambiguous, because months have different lengths. For example, adding one month to August 31 would result in September 31, which doesn't exist. For these cases, the overflow option tells what to do:

Additionally, if the result is earlier or later than the range of dates that Temporal.PlainDateTime can represent (approximately half a million years centered on the Unix epoch), then this method will throw a RangeError regardless of overflow.

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

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.add({ years: 20, months: 4, nanoseconds: 500 }); // => 2016-04-07T03:24:30.000004

dt = Temporal.PlainDateTime.from('2019-01-31T15:30');
dt.add({ months: 1 }); // => 2019-02-28T15:30:00
dt.add({ months: 1 }, { overflow: 'reject' }); // => throws

datetime.subtract(duration: Temporal.Duration | object | string, options?: object) : Temporal.PlainDateTime

Parameters:

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

This method subtracts duration from datetime, returning a point in time that is in the past relative to datetime.

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().

Some subtractions may be ambiguous, because months have different lengths. For example, subtracting one month from July 31 would result in June 31, which doesn't exist. For these cases, the overflow option tells what to do:

Additionally, if the result is earlier or later than the range of dates that Temporal.PlainDateTime can represent (approximately half a million years centered on the Unix epoch), then this method will throw a RangeError regardless of overflow.

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

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.subtract({ years: 20, months: 4, nanoseconds: 500 }); // => 1975-08-07T03:24:30.000003

dt = Temporal.PlainDateTime.from('2019-03-31T15:30');
dt.subtract({ months: 1 }); // => 2019-02-28T15:30:00
dt.subtract({ months: 1 }, { overflow: 'reject' }); // => throws

datetime.until(other: Temporal.PlainDateTime | object | string, options?: object) : Temporal.Duration

Parameters:

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

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

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

The largestUnit option 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 "seconds", for example. However, a difference of 30 seconds will still be 30 seconds even if largestUnit is "hours". A value of 'auto' means 'day', unless smallestUnit is 'year', 'month', or 'week', in which case largestUnit is equal to smallestUnit.

By default, the largest unit in the result is days. This is because months and years can be different lengths depending on which month is meant and whether the year is a leap year.

You can round the result using the smallestUnit, roundingIncrement, and roundingMode options. These behave as in the Temporal.Duration.round() method, but increments of days and larger are allowed. Because rounding to an increment expressed in days or larger units requires a reference point, datetime is used as the starting point in that case. The default is to do no rounding.

Take care when using milliseconds, microseconds, or nanoseconds as the largest unit. For some durations, the resulting value may overflow Number.MAX_SAFE_INTEGER and lose precision in its least significant digit(s). Nanoseconds values will overflow and lose precision after about 104 days. Microseconds can fit about 285 years without losing precision, and milliseconds can handle about 285,000 years without losing precision.

Computing the difference between two date/times in different calendar systems is not supported. If you need to do this, choose the calendar in which the computation takes place by converting one of the dates with datetime.withCalendar().

Usage example:

dt1 = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt2 = Temporal.PlainDateTime.from('2019-01-31T15:30');
dt1.until(dt2);
  // => P8456DT12H5M29.9999965S
dt1.until(dt2, { largestUnit: 'year' });
  // => P23Y1M24DT12H5M29.9999965S
dt2.until(dt1, { largestUnit: 'year' });
  // => -P23Y1M24DT12H5M29.9999965S
dt1.until(dt2, { largestUnit: 'nanosecond' });
  // => PT730641929.999996544S
  // (precision lost)

// Rounding, for example if you don't care about sub-seconds
dt1.until(dt2, { smallestUnit: 'second' });
  // => P8456DT12H5M29S

// Months and years can be different lengths
let [jan1, feb1, mar1] = [1, 2, 3].map((month) =>
  Temporal.PlainDateTime.from({ year: 2020, month, day: 1 }));
jan1.until(feb1);                            // => P31D
jan1.until(feb1, { largestUnit: 'month' }); // => P1M
feb1.until(mar1);                            // => P29D
feb1.until(mar1, { largestUnit: 'month' }); // => P1M
jan1.until(mar1);                            // => P60D

datetime.since(other: Temporal.PlainDateTime | object | string, options?: object) : Temporal.Duration

Parameters:

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

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

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

Usage example:

dt1 = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt2 = Temporal.PlainDateTime.from('2019-01-31T15:30');
dt2.since(dt1); // => P8456DT12H5M29.9999965S

datetime.round(roundTo: string | object) : Temporal.PlainDateTime

Parameters:

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

Rounds datetime to the given unit and increment, and returns the result as a new Temporal.PlainDateTime 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.)

If smallestUnit is 'day', then 1 is the only allowed value for roundingIncrement.

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:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');

// Round to a particular unit
dt.round({ smallestUnit: 'hour' }); // => 1995-12-07T03:00:00
// Round to an increment of a unit, e.g. half an hour:
dt.round({ roundingIncrement: 30, smallestUnit: 'minute' });
  // => 1995-12-07T03:30:00
// Round to the same increment but round down instead:
dt.round({ roundingIncrement: 30, smallestUnit: 'minute', roundingMode: 'floor' });
  // => 1995-12-07T03:00:00

datetime.equals(other: Temporal.PlainDateTime | object | string) : boolean

Parameters:

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

Compares two Temporal.PlainDateTime objects for equality.

This function exists because it's not possible to compare using datetime == other or datetime === 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 dates/times occur, then this function may be less typing and more efficient than Temporal.PlainDateTime.compare.

Note that this function will return false if the two objects have different calendar properties, even if the actual dates and times are equal.

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

Example usage:

dt1 = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt2 = Temporal.PlainDateTime.from('2019-01-31T15:30');
dt1.equals(dt2); // => false
dt1.equals(dt1); // => true

datetime.toString(options?: object) : string

Parameters:

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

This method overrides the Object.prototype.toString() method and provides a convenient, unambiguous string representation of datetime. The string can be passed to Temporal.PlainDateTime.from() to create a new Temporal.PlainDateTime 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.

Normally, a calendar annotation is shown when datetime's calendar is not the ISO 8601 calendar. By setting the calendarName option to 'always' or 'never' this can be overridden to always or never show the annotation, respectively. Normally not necessary, a value of 'critical' is equivalent to 'always' but the annotation will contain an additional ! for certain interoperation use cases. For more information on the calendar annotation, see the Temporal string formats documentation.

Example usage:

dt = Temporal.PlainDateTime.from({
  year: 1999,
  month: 12,
  day: 31,
  hour: 23,
  minute: 59,
  second: 59,
  millisecond: 999,
  microsecond: 999,
  nanosecond: 999
});
dt.toString(); // => '1999-12-31T23:59:59.999999999'

dt.toString({ smallestUnit: 'minute' });    // => '1999-12-31T23:59'
dt.toString({ fractionalSecondDigits: 0 }); // => '1999-12-31T23:59:59'
dt.toString({ fractionalSecondDigits: 4 }); // => '1999-12-31T23:59:59.9999'
dt.toString({ fractionalSecondDigits: 8, roundingMode: 'halfExpand' });
// => '2000-01-01T00:00:00.00000000'

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

Parameters:

Returns: a language-sensitive representation of datetime.

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

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

NOTE: Unlike in Temporal.Instant.prototype.toLocaleString(), options.timeZone will have no effect, because Temporal.PlainDateTime carries no time zone information. It's not always possible to uniquely determine the localized time zone name using the Temporal.PlainDateTime instance and the options.timeZone. Therefore, to display a localized date and time including its time zone, convert the Temporal.PlainDateTime to a Temporal.ZonedDateTime or Temporal.Instant and then call the toLocaleString() method.

Example usage:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.toLocaleString(); // example output: 1995-12-07, 3:24:30 a.m.
dt.toLocaleString('de-DE'); // example output: 7.12.1995, 03:24:30
dt.toLocaleString('de-DE', { timeZone: 'Europe/Berlin', weekday: 'long' }); // => 'Donnerstag'
dt.toLocaleString('en-US-u-nu-fullwide-hc-h12'); // => '12/7/1995, 3:24:30 AM'

datetime.toJSON() : string

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

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

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

Example usage:

const event = {
  id: 311,
  name: 'FictionalConf 2018',
  openingDateTime: Temporal.PlainDateTime.from('2018-07-06T10:00'),
  closingDateTime: Temporal.PlainDateTime.from('2018-07-08T18:15')
};
const str = JSON.stringify(event, null, 2);
console.log(str);
// =>
// {
//   "id": 311,
//   "name": "FictionalConf 2018",
//   "openingDateTime": "2018-07-06T10:00",
//   "closingDateTime": "2018-07-08T18:15"
// }

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

datetime.valueOf()

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

datetime.toZonedDateTime(timeZone : object | string, options?: object) : Temporal.ZonedDateTime

Parameters:

Returns: A Temporal.ZonedDateTime object representing the calendar date and wall-clock time from dateTime projected into timeZone.

This method converts a Temporal.PlainDateTime to a Temporal.ZonedDateTime by adding a time zone.

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 the case of ambiguity caused by DST or other time zone changes, the disambiguation option controls how to resolve the ambiguity:

When interoperating with existing code or services, 'compatible' mode 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 if 'compatible' or 'later' is used or the post-transition time zone offset if 'earlier' is used. This behavior avoids exceptions when converting nonexistent Temporal.PlainDateTime values to Temporal.ZonedDateTime, but it also means that values during these periods will result in a different Temporal.PlainDateTime in "round-trip" conversions to Temporal.ZonedDateTime and back again.

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

If the result is earlier or later than the range that Temporal.ZonedDateTime can represent (approximately half a million years centered on the Unix epoch), then a RangeError will be thrown, no matter the value of disambiguation.

datetime.toPlainDate() : Temporal.PlainDate

Returns: a Temporal.PlainDate object that is the same as the date portion of datetime.

datetime.toPlainYearMonth() : Temporal.PlainYearMonth

Returns: a Temporal.PlainYearMonth object that is the same as the year and month of datetime.

datetime.toPlainMonthDay() : Temporal.PlainMonthDay

Returns: a Temporal.PlainMonthDay object that is the same as the month and day of datetime.

datetime.toPlainTime() : Temporal.PlainTime

Returns: a Temporal.PlainTime object that is the same as the wall-clock time portion of datetime.

The above four methods can be used to convert Temporal.PlainDateTime into a Temporal.PlainDate, Temporal.PlainYearMonth, Temporal.PlainMonthDay, or Temporal.PlainTime respectively. The converted object carries a copy of all the relevant fields of datetime (for example, in toPlainDate(), the year, month, and day properties are copied.)

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
dt.toPlainDate(); // => 1995-12-07
dt.toPlainYearMonth(); // => 1995-12
dt.toPlainMonthDay(); // => 12-07
dt.toPlainTime(); // => 03:24:30.0000035

datetime.getCalendar(): object

Returns: a Temporal.Calendar instance or plain object representing the calendar in which datetime is reckoned.

This method is mainly useful if you need an object on which to call calendar methods. Most code will not need to use it.

datetime.getISOFields(): { isoYear: number, isoMonth: number, isoDay: number, isoHour: number, isoMinute: number, isoSecond: number, isoMillisecond: number, isoMicrosecond: number, isoNanosecond: number, calendar: string | object }

Returns: a plain object with properties expressing datetime in the ISO 8601 calendar, as well as the calendar (usually a string, but may be an object) in which datetime is reckoned.

This method is mainly useful if you are implementing a custom calendar. Most code will not need to use it.

Usage example:

dt = Temporal.PlainDateTime.from('1995-12-07T03:24:30.000003500');
f = dt.getISOFields();
f.isoDay; // => 7
// Fields correspond exactly to constructor arguments:
dt2 = new Temporal.PlainDateTime(f.isoYear, f.isoMonth, f.isoDay, f.isoHour, f.isoMinute,
  f.isoSecond, f.isoMillisecond, f.isoMicrosecond, f.isoNanosecond, f.calendar);
dt.equals(dt2); // => true

// Date in other calendar
dt = dt.withCalendar('hebrew');
dt.day; // => 14
dt.getISOFields().isoDay; // => 7

// Most likely what you need is this:
dt.withCalendar('iso8601').day; // => 7