PlainDateTime
Create and Parse
Constructor
pdt = new Temporal.PlainDateTime(
2024, // isoYear
11, // isoMonth
4, // isoDay
3, // isoHour (optional)
5, // isoMinute (optional)
2, // isoSecond (optional)
1, // isoMillisecond (optional)
1, // isoMicrosecond (optional)
1, // isoNanosecond (optional)
'gregory', // calendar (optional)
)From Fields
pdt = Temporal.PlainDate.from({
year: 2024, // or era+eraYear
month: 11, // or monthCode
day: 4,
hour: 3, // (optional)
minute: 5, // (optional)
second: 2, // (optional)
millisecond: 1, // (optional)
microsecond: 1, // (optional)
nanosecond: 1, // (optional)
calendar: 'gregory', // (optional)
})You can also pass-in a ZonedDateTime!
From String
pdt = Temporal.PlainDate.from(
'2024-03-06T11:29:06.340442931'
)Now
Multiple methods:
Temporal.Now.plainDateTimeISO()
Temporal.Now.plainDateTime()
pdt = Temporal.Now.plainDateTimeISO('America/Chicago')
// or
pdt = Temporal.Now.plainDateTime({
timeZone: 'America/Chicago',
calendar: 'gregory'
})Get and Set
Common setter method.. new instance (immutable)..
.with()
You can combine multiple!
Here we go...
Year
Either use the simple year number or the era + eraYear (for supported calendars only).
.year
// get
pdt.year // 2024
// set
pdt2 = pdt.with({ year: 2025 }).era and .eraYear
pdt = Temporal.Now.plainDateTime({
timeZone: 'America/Chicago',
calendar: 'gregory'
})
// get
pdt.era // 'bce'
pdt.eraYear // 2024
// set
pdt2 = pdt.with({
era: 'bc',
eraYear: 2,
}).inLeapYear
pdt.inLeapYear // falseCan't set.
Month
Is 1-based!
Either use the simple month number or the more portable monthCode.
.month
// get
pdt.month // 3
// set
pdt2 = pdt.with({ month: 4 }).monthCode
// get
pdt.monthCode // 'M03'
// set
pdt2 = pdt.with({ monthCode: 'M04' }).monthsInYear
Certain calendar systems might have different months in year:
pdt = Temporal.Now.plainDateTime({
timeZone: 'America/Chicago',
calendar: 'hebrew'
})
// get
pdt.monthsInYear // 12Day of Month
Is 1-based!
The day-of-month, often simply called the date, is the day property in Temporal:
.day
// get
pdt.day // 6 (for March 6th)
// set
pdt.with({ day: 19 })Time
The wall-clock time has multiple properties:
.hour
// get
pdt.hour // 9
// set
pdt2 = pdt.with({ hour: 9 }).minute
// get
pdt.minute // 9
// set
pdt2 = pdt.with({ minute: 9 }).second
// get
pdt.second // 9
// set
pdt2 = pdt.with({ second: 9 }).millisecond
// get
pdt.millisecond // 9
// set
pdt2 = pdt.with({ millisecond: 9 }).microsecond
// get
pdt.microsecond // 9
// set
pdt2 = pdt.with({ microsecond: 9 }).nanosecond
// get
pdt.nanosecond // 9
// set
pdt2 = pdt.with({ nanosecond: 9 })Calendar
Methods:
.calendarId
.getCalendar()
.withCalendar()
// get
calendarId = pdt.calendarId // 'iso8601'
calendarObj = pdt.getCalendar() // Temporal.Calendar {}
// set
pdt2 = pdt.withCalendar('gregory')Read more about Calendar objects.
Week
Two concepts.
.weekOfYear
.yearOfWeek
Only works for supported calendars!
// get
pdt.weekOfYear // 89
pdt.yearOfWeek // 2024
// set weekOfYear
pdt1 = pdt.add({ weeks: 8 - pdt.weekOfYear })import { withWeekOfYear } from 'temporal-utils'
pdt1 = withWeekOfYear(pdt, 8)Day of Week
Explain 1 means Monday... This is REGARDLESS of locale. Always ISO
.dayOfWeek
// get
pdt.dayOfWeek // 4 (Thursday)
// set
pdt2 = pdt.add({ days: 6 - pdt.dayOfWeek })import { withDayOfWeek } from 'temporal-utils'
pdt2 = withDayOfWeek(pdt, 6)Day of Year
Is 1-based!!!
.dayOfYear
// get
pdt.dayOfYear // 89
// set
pdt2 = pdt.add({ days: 48 - pdt.dayOfYear })import { withDayOfYear } from 'temporal-utils'
pdt2 = withDayOfYear(pdt, 48)Days in Unit
Simple
.daysInYear
.daysInMonth
.daysInWeek
pdt.daysInYear // 366
pdt.daysInMonth // 23
pdt.daysInWeek // 7ISO Fields
// get
isoFields = pdt.getISOFields()
// {
// isoYear: 234,
// isoMonth: 234,
// isoDay: 234,
// isoHour: 234,
// isoMinute: 123,
// isoSecond: 123,
// isoMillisecond: 123,
// isoMicrosecond: 234,
// isoNanosecond: 123
// calendar: 'gregory',
// }
// create-from
pdt2 = new Temporal.PlainDateTime(
isoFields.isoYear,
isoFields.isoMonth,
isoFields.isoDay,
isoFields.isoHour,
isoFields.isoMinute,
isoFields.isoSecond,
isoFields.isoMillisecond,
isoFields.isoMicrosecond,
isoFields.isoNanosecond,
isoFields.calendar,
)Math
Add and Subtract
Give a Duration or Duration-like fields:
.add()
pdt = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt2 = pdt.add({
year: 1,
months: 2,
})
// '2024-03-06T13:03:21.596195335'.subtract()
pdt = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt2 = pdt.subtract({
year: 1,
months: 2,
})
// '2024-03-06T13:03:21.596195335'There are options about overflow!
Round
For settings like roundingIncrement and roundingMode.
Only allows rounding to day/time! Not larger units like years/months/week!
Day:
pdt2 = pdt.round('day')
// or
pdt2 = pdt.round({
smallestUnit: 'day',
roundingMode: 'halfExpand' // or trunc/floor/ceil/etc
roundingIncrement: 1,
})Time:
pdt2 = pdt.round('hour') // or minute/second/millisecond/microsecond
// or
pdt2 = pdt.round({
smallestUnit: 'hour', // or minute/second/millisecond/microsecond
roundingMode: 'halfExpand' // or trunc/floor/ceil/etc
roundingIncrement: 1,
})Year:
import { roundToYear } from 'temporal-utils'
pdt2 = roundToYear(pdt)
// or
pdt2 = roundToYear(pdt, {
roundingMode: 'halfExpand' // or trunc/floor/ceil/etc
roundingIncrement: 1,
})Month:
import { roundToMonth } from 'temporal-utils'
pdt2 = roundToMonth(pdt)
// or
pdt2 = roundToMonth(pdt, {
roundingMode: 'halfExpand' // or trunc/floor/ceil/etc
roundingIncrement: 1,
})Week:
import { roundToWeek } from 'temporal-utils'
pdt2 = roundToWeek(pdt)
// or
pdt2 = roundToWeek(pdt, {
roundingMode: 'halfExpand' // or trunc/floor/ceil/etc
roundingIncrement: 1,
})Start of Unit
Start of year (might not be midnight):
pdt2 = pdt.with({ month: 1, day: 1 })
.withPlainTime()import { startOfYear } from 'temporal-utils'
pdt2 = startOfYear(pdt)Start of month (might not be midnight):
pdt2 = pdt.with({ day: 1 })
.withPlainTime()import { startOfMonth } from 'temporal-utils'
pdt2 = startOfMonth(pdt)Also PLEASE look at PlainDateTime::toPlainYearMonth
Start of week:
pdt2 = pdt.add({ days: 1 - pdt.dayOfWeek })import { startOfWeek } from 'temporal-utils'
pdt2 = startOfWeek(pdt)Start of day (might not be midnight):
pdt2 = pdt.withPlainTime()Start of hour:
pdt2 = pdt.round({
smallestUnit: 'hour',
roundingMode: 'floor',
})Also PLEASE look at PlainDateTime::toPlainDate
import { startOfHour } from 'temporal-utils'
pdt2 = startOfHour(pdt)Start of minute:
pdt2 = pdt.round({
smallestUnit: 'minute',
roundingMode: 'floor',
})import { startOfMinute } from 'temporal-utils'
pdt2 = startOfMinute(pdt)Start of second:
pdt2 = pdt.round({
smallestUnit: 'second',
roundingMode: 'floor',
})import { startOfSecond } from 'temporal-utils'
pdt2 = startOfSecond(pdt)Start of millisecond:
pdt2 = pdt.round({
smallestUnit: 'millisecond',
roundingMode: 'floor',
})import { startOfMillisecond } from 'temporal-utils'
pdt2 = startOfMillisecond(pdt)Start of microsecond:
pdt2 = pdt.round({
smallestUnit: 'microsecond',
roundingMode: 'floor',
})import { startOfMicrosecond } from 'temporal-utils'
pdt2 = startOfMicrosecond(pdt)End of Unit
Explain inclusive vs exclusive.
End of year (might not be midnight):
pdt2 = pdt.with({ month: 1, day: 1 })
.withPlainTime()
.add({ years: 1 }) // sufficient for exclusive end
.subtract({ nanoseconds: 1 }) // inclusive endimport { endOfYearExcl, endOfYearIncl } from 'temporal-utils'
pdt2 = endOfYearExcl(pdt)
pdt2 = endOfYearIncl(pdt)End of month (might not be midnight):
pdt2 = pdt.with({ day: 1 })
.withPlainTime()
.add({ months: 1 }) // sufficient for exclusive end
.subtract({ nanoseconds: 1 }) // inclusive endimport { endOfMonthExcl, endOfMonthIncl } from 'temporal-utils'
pdt2 = endOfMonthExcl(pdt)
pdt2 = endOfMonthIncl(pdt)End of day (might not be midnight):
pdt2 = pdt.add({ days: 1 })
.withPlainTime() // sufficient for exclusive end
.subtract({ nanoseconds: 1 }) // inclusive endimport { endOfDayExcl, endOfDayIncl } from 'temporal-utils'
pdt2 = endOfDayExcl(pdt)
pdt2 = endOfDayIncl(pdt)End of hour:
pdt2 = pdt.round({ // sufficient for exclusive end
smallestUnit: 'hour',
roundingMode: 'ceil',
}).subtract({ nanoseconds: 1 }) // inclusive endimport { endOfHourExcl, endOfHourIncl } from 'temporal-utils'
pdt2 = endOfHourExcl(pdt)
pdt2 = endOfHourIncl(pdt)End of minute:
pdt2 = pdt.round({ // sufficient for exclusive end
smallestUnit: 'minute',
roundingMode: 'ceil',
}).subtract({ nanoseconds: 1 }) // inclusive endimport { endOfMinuteExcl, endOfMinuteIncl } from 'temporal-utils'
pdt2 = endOfMinuteExcl(pdt)
pdt2 = endOfMinuteIncl(pdt)End of second:
pdt2 = pdt.round({ // sufficient for exclusive end
smallestUnit: 'second',
roundingMode: 'ceil',
}).subtract({ nanoseconds: 1 }) // inclusive endimport { endOfSecondExcl, endOfSecondIncl } from 'temporal-utils'
pdt2 = endOfSecondExcl(pdt)
pdt2 = endOfSecondIncl(pdt)End of millisecond:
pdt2 = pdt.round({ // sufficient for exclusive end
smallestUnit: 'millisecond',
roundingMode: 'ceil',
}).subtract({ nanoseconds: 1 }) // inclusive endimport { endOfMillisecondExcl, endOfMillisecondIncl } from 'temporal-utils'
pdt2 = endOfMillisecondExcl(pdt)
pdt2 = endOfMillisecondIncl(pdt)End of microsecond:
pdt2 = pdt.round({ // sufficient for exclusive end
smallestUnit: 'microsecond',
roundingMode: 'ceil',
}).subtract({ nanoseconds: 1 }) // inclusive endimport { endOfMicrosecondExcl, endOfMicrosecondIncl } from 'temporal-utils'
pdt2 = endOfMicrosecondExcl(pdt)
pdt2 = endOfMicrosecondIncl(pdt)Difference
You can use .since instead! but best to be consistent with .until!
roundingMode:
- 'halfExpand' - like Math.round() - the default
- 'trunc' - like Math.trunc()
- 'floor' - like Math.floor()
- 'ceil' - like Math.ceil()
With all units. A Duration object.
pdt1 = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt2 = Temporal.PlainDateTime.from('2024-03-06T12:30')
dur = pdt1.until(pdt2, {
largestUnit: 'year',
smallestUnit: 'day',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
})
// Temporal.Duration {
// years: 1,
// months: 3,
// days: 2,
// hours: 0,
// minutes: 0,
// ...
// }With years:
yearsRounded = pdt1.until(pdt2, {
largestUnit: 'year',
smallestUnit: 'year',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).years // 6
yearsExact = pdt1.until(pdt2, {
largestUnit: 'year',
}).total({
unit: 'year',
relativeTo: pdt1,
}) // 6.5import { diffYears } from 'temporal-utils'
yearsRounded = diffYears(pdt1, pdt2, 'halfExpand')
yearsExact = diffYears(pdt1, pdt2)With months:
monthsRounded = pdt1.until(pdt2, {
largestUnit: 'month',
smallestUnit: 'month',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).months // 6
monthsExact = pdt1.until(pdt2, {
largestUnit: 'month',
}).total({
unit: 'month',
relativeTo: pdt1,
}) // 6.5import { diffMonths } from 'temporal-utils'
monthsRounded = diffMonths(pdt1, pdt2, 'halfExpand')
monthsExact = diffMonths(pdt1, pdt2)With weeks:
weeksRounded = pdt1.until(pdt2, {
largestUnit: 'week',
smallestUnit: 'week',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).weeks // 6
weeksExact = pdt1.until(pdt2, {
largestUnit: 'week',
}).total({
unit: 'week',
relativeTo: pdt1,
}) // 6.5import { diffWeeks } from 'temporal-utils'
weeksRounded = diffWeeks(pdt1, pdt2, 'halfExpand')
weeksExact = diffWeeks(pdt1, pdt2)With days:
daysRounded = pdt1.until(pdt2, {
largestUnit: 'day',
smallestUnit: 'day',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).days // 6
daysExact = pdt1.until(pdt2, {
largestUnit: 'day',
}).total({
unit: 'day',
relativeTo: pdt1,
}) // 6.5import { diffDays } from 'temporal-utils'
daysRounded = diffDays(pdt1, pdt2, 'halfExpand')
daysExact = diffDays(pdt1, pdt2)With hours:
hoursRounded = pdt1.until(pdt2, {
largestUnit: 'hour',
smallestUnit: 'hour',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).hours // 6
hoursExact = pdt1.until(pdt2, {
largestUnit: 'hour',
}).total('hour') // 6.5import { diffHours } from 'temporal-utils'
hoursRounded = diffHours(pdt1, pdt2, 'halfExpand')
hoursExact = diffHours(pdt1, pdt2)With minutes:
minutesRounded = pdt1.until(pdt2, {
largestUnit: 'hour',
smallestUnit: 'hour',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).hours // 6
minutesExact = pdt1.until(pdt2, {
largestUnit: 'hour',
}).total('hour') // 6.5import { diffMinutes } from 'temporal-utils'
minutesRounded = diffMinutes(pdt1, pdt2, 'halfExpand')
minutesExact = diffMinutes(pdt1, pdt2)With seconds:
secondsRounded = pdt1.until(pdt2, {
largestUnit: 'second',
smallestUnit: 'second',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).seconds // 6
secondsExact = pdt1.until(pdt2, {
largestUnit: 'second',
}).total('second') // 6.5import { diffSeconds } from 'temporal-utils'
secondsRounded = diffSeconds(pdt1, pdt2, 'halfExpand')
secondsExact = diffSeconds(pdt1, pdt2)With milliseconds:
msRounded = pdt1.until(pdt2, {
largestUnit: 'millisecond',
smallestUnit: 'millisecond',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).milliseconds // 6
msExact = pdt1.until(pdt2, {
largestUnit: 'millisecond',
}).total('millisecond') // 6.5import { diffMilliseconds } from 'temporal-utils'
msRounded = diffMilliseconds(pdt1, pdt2, 'halfExpand')
msExact = diffMilliseconds(pdt1, pdt2)With microseconds:
μsRounded = pdt1.until(pdt2, {
largestUnit: 'microsecond',
smallestUnit: 'microsecond',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
}).microseconds // 6
μsExact = pdt1.until(pdt2, {
largestUnit: 'microsecond',
}).total('microsecond') // 6.5import { diffMicroseconds } from 'temporal-utils'
μsRounded = diffMicroseconds(pdt1, pdt2, 'halfExpand')
μsExact = diffMicroseconds(pdt1, pdt2)With nanoseconds:
nsRounded = pdt1.until(pdt2, {
largestUnit: 'nanosecond',
smallestUnit: 'nanosecond',
roundingMode: 'halfExpand', // or trunc/floor/ceil/etc
roundingIncrement: 10,
}).nanoseconds
nsUnrounded = pdt2.epochNanoseconds - pdt1.epochNanosecondsimport { diffNanoseconds } from 'temporal-utils'
nsRounded = diffNanoseconds(pdt1, pdt2, 'halfExpand')
nsUnrounded = diffNanoseconds(pdt1, pdt2)Compare and Sort
Compare:
pdt1 = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt2 = Temporal.PlainDateTime.from('2024-03-06T12:30')
Temporal.PlainDateTime.compare(pdt1, pdt2)
// -1 because pdt1 < pdt2
Temporal.PlainDateTime.compare(pdt1, pdt2)
// 1 because pdt1 > pdt2
Temporal.PlainDateTime.compare(pdt1, pdt1)
// 0 because pdt1 = zdtPastSort:
pdtArray = [
Temporal.PlainDateTime.from('2024-03-06T12:30'),
Temporal.PlainDateTime.from('2024-03-06T12:30'),
Temporal.PlainDateTime.from('2024-05-06T12:30')
].sort(
Temporal.PlainDateTime.compare
)Equality
epochNanoseconds, timeZone, and calendar must be identical.
pdt1 = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt2 = Temporal.PlainDateTime.from('2024-03-06T12:30')
pdt1.equals(pdt2) // false
pdt1.equals(pdt1) // true (of course it's equal to self)Stringify
ISO String
pdt.toString() // '2024-03-06T12:30'For options, consult the spec.
Localized String
For options, consult Intl.DateTimeFormat options. The timeZone options is prohibited!
It's possible to call directly on the object:
// current locale
pdt.toLocaleString() // '3/6/2024, 3:58:45'
// specific locale
pdt.toLocaleString('fr') // '06/03/2024 15:59:31'
// specific locale + options
pdt.toLocaleString('fr', { // 'mercredi 6 mars 2024'
dateStyle: 'full',
})However, it's much more performant to reuse a format:
dtf = new Intl.DateTimeFormat('fr', {
dateStyle: 'full'
})
dtf.format(pdt) // 'mercredi 6 mars 2024'Convert
Legacy Date
PlainDateTime -> Date
tzId = Temporal.Now.timeZoneId() // system time zone
tzId = 'America/Chicago' // OR a specific time zone
legacyDate = new Date(
pdt.toZonedDateTime(tzId).epochMilliseconds
)Date -> PlainDateTime
tzId = Temporal.Now.timeZoneId() // system time zone
tzId = 'America/Chicago' // OR a specific time zone
// ISO calendar
pdt = legacyDate
.toTemporalInstant()
.toZonedDateTimeISO(tzId)
.toPlainDateTime()
// specific calendar
pdt = legacyDate
.toTemporalInstant()
.toZonedDateTime({ timeZone: tzId, calendar: 'gregory' })
.toPlainDateTime()Instant
PlainDateTime -> Instant
tzId = Temporal.Now.timeZoneId() // system time zone
tzId = 'America/Chicago' // OR a specific time zone
inst = pdt.toZonedDateTime(tzId).toInstant()Instant -> PlainDateTime
tzId = Temporal.Now.timeZoneId() // system time zone
tzId = 'America/Chicago' // OR a specific time zone
// ISO calendar
pdt = inst
.toZonedDateTimeISO(tzId)
.toPlainDateTime()
// specific calendar
pdt = inst
.toZonedDateTime({ timeZone: tzId, calendar: 'gregory' })
.toPlainDateTime()ZonedDateTime
PlainDateTime -> ZonedDateTime
tzId = Temporal.Now.timeZoneId() // system time zone
tzId = 'America/Chicago' // OR a specific time zone
zdt = pdt.toZonedDateTime(tzId)Second argument can give more control.
ZonedDateTime -> PlainDateTime
pdt = zdt.toPlainDateTime()PlainDate
PlainDateTime -> PlainDate
pd = pdt.toPlainDate()PlainDate -> PlainDateTime
pdt = pd.toPlainDateTime('05:00') // optional, default 00:00PlainTime
PlainDateTime -> PlainTime
pt = pdt.toPlainTime()PlainTime -> PlainDateTime
pdt = pt.toPlainDateTime('2024-04-04')PlainYearMonth
PlainDateTime -> PlainYearMonth
pym = pdt.toPlainYearMonth()PlainYearMonth -> PlainDateTime
pdt = pym.toPlainDate({ day: 4 })
.toPlainDateTime('05:00') // optional, default 00:00PlainMonthDay
PlainDateTime -> PlainMonthDay
pmd = pdt.toPlainMonthDay()PlainMonthDay -> PlainDateTime
pdt = pmd.toPlainDate({ year: 2017 })
.toPlainDateTime('05:00')