npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

temporal-utils

v1.0.1

Published

Convenience helpers for native Temporal objects

Readme

temporal-utils

Small, application-level helpers for working with native Temporal objects

Most helpers preserve the input type. For example, passing a Temporal.PlainDateTime to startOfMonth returns a Temporal.PlainDateTime, while passing a Temporal.ZonedDateTime returns a Temporal.ZonedDateTime.

Installation

npm install temporal-utils

temporal-utils does not ship a Temporal implementation of its own — a global Temporal must already exist at runtime. See Requirements.

Usage

Import the helpers you need from the package root and call them on native Temporal objects. Each helper accepts a range of Temporal types and gives you back the same type you passed in:

import { startOfMonth, diffDays } from 'temporal-utils'

// Pass a PlainDate, get a PlainDate back
startOfMonth(Temporal.PlainDate.from('2024-07-20')).toString()
// '2024-07-01'

// Pass a ZonedDateTime, get a ZonedDateTime back
startOfMonth(
  Temporal.ZonedDateTime.from('2024-07-20T12:30[America/New_York]'),
).toString()
// '2024-07-01T00:00:00-04:00[America/New_York]'

diffDays(
  Temporal.PlainDate.from('2024-07-01'),
  Temporal.PlainDate.from('2024-07-20'),
)
// 19

Requirements

temporal-utils operates on native Temporal objects but does not include a Temporal implementation of its own. A global Temporal must already exist at runtime — note that every example below references Temporal.* directly to build its inputs. Ensure one is present in one of two ways:

  • Native Temporal — available in newer browsers and runtimes, but support is still rolling out and remains incomplete.

  • A polyfill — recommended for now. We suggest temporal-polyfill, which installs a global Temporal:

    import 'temporal-polyfill/global'

Function Reference

Field Replacement

These helpers fill gaps where Temporal exposes calendar-derived fields such as dayOfYear, dayOfWeek, and weekOfYear, but does not provide direct with({ ... }) fields for replacing them.

All field replacement helpers:

  • accept Temporal.PlainDate, Temporal.PlainDateTime, or Temporal.ZonedDateTime
  • truncate numeric input toward zero before applying it
  • accept Temporal field overflow options: { overflow: 'constrain' } or { overflow: 'reject' }
  • default overflow behavior to 'constrain'

withDayOfYear

Signature:

function withDayOfYear<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(
  date: T,
  dayOfYear: number,
  options?: Temporal.OverflowOptions,
): T

Returns the same calendar year with dayOfYear replaced. The time, time zone, and calendar are preserved.

import { withDayOfYear } from 'temporal-utils'

const date = Temporal.PlainDate.from('2024-02-27')

withDayOfYear(date, 5).toString()
// '2024-01-05'

withDayOfYear(date, 500).toString()
// '2024-12-31'

withDayOfYear(date, 500, { overflow: 'reject' })
// RangeError

withDayOfWeek

Signature:

function withDayOfWeek<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(
  date: T,
  dayOfWeek: number,
  options?: Temporal.OverflowOptions,
): T

Returns the same ISO week with dayOfWeek replaced. Temporal uses ISO weekday numbers: Monday is 1 and Sunday is 7.

import { withDayOfWeek } from 'temporal-utils'

const date = Temporal.PlainDate.from('2024-02-27') // Tuesday

withDayOfWeek(date, 4).toString()
// '2024-02-29'

withDayOfWeek(date, 8).toString()
// '2024-03-03'

withWeekOfYear

Signature:

function withWeekOfYear<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(
  date: T,
  weekOfYear: number,
  options?: Temporal.OverflowOptions,
): T

Returns the same ISO week-year with weekOfYear replaced, preserving the current day of week. This helper is ISO-only and throws a RangeError for calendars where Temporal does not expose ISO week fields.

import { withWeekOfYear } from 'temporal-utils'

const date = Temporal.PlainDate.from('2024-02-27') // Tuesday, week 9

withWeekOfYear(date, 27).toString()
// '2024-07-02'

withWeekOfYear(date.withCalendar('hebrew'), 27)
// RangeError

Difference Helpers

Single-unit difference helpers return a number for date0.until(date1). The helpers are directional: reversing the arguments reverses the sign.

If no options are supplied, the result is the exact total in the requested unit. Pass a RoundingMode string or a RoundingMathOptions object to request Temporal rounding behavior for that unit.

import { diffDays, diffMonths } from 'temporal-utils'

const start = Temporal.PlainDate.from('2024-02-20')
const end = Temporal.PlainDate.from('2024-04-10')

diffMonths(start, end)
// approximately 1.677...

diffMonths(start, end, 'floor')
// 1

diffDays(start, end, { roundingMode: 'ceil', roundingIncrement: 7 })
// 56

Date and calendar unit helpers use relativeTo internally so totals account for calendar units. For Temporal.ZonedDateTime, totals also account for time-zone transitions. Time-unit helpers produce elapsed-time totals.

diffYears

Signature:

function diffYears(
  date0: Temporal.PlainYearMonth | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.PlainYearMonth | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in years. Supported input types are Temporal.PlainYearMonth, Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffMonths

Signature:

function diffMonths(
  date0: Temporal.PlainYearMonth | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.PlainYearMonth | Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in months. Supported input types are Temporal.PlainYearMonth, Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffWeeks

Signature:

function diffWeeks(
  date0: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in weeks. Supported input types are Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffDays

Signature:

function diffDays(
  date0: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in days. Supported input types are Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffHours

Signature:

function diffHours(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in hours. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffMinutes

Signature:

function diffMinutes(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in minutes. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffSeconds

Signature:

function diffSeconds(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in seconds. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffMilliseconds

Signature:

function diffMilliseconds(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in milliseconds. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffMicroseconds

Signature:

function diffMicroseconds(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in microseconds. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

diffNanoseconds

Signature:

function diffNanoseconds(
  date0: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  date1: Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
  options?: RoundingMode | RoundingMathOptions,
): number

Returns the difference in nanoseconds. Supported input types are Temporal.Instant, Temporal.PlainTime, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

Rounding Helpers

Calendar rounding helpers return the closest start of the named unit. They are useful because Temporal's native .round() APIs cover day and smaller units, but not every larger calendar unit in a uniform way across date-like types.

If options or options.roundingMode is omitted, roundingMode defaults to 'halfExpand'. Pass a RoundingMode string as shorthand for { roundingMode }.

RoundingMathOptions must not include smallestUnit; the helper name supplies the unit. For the year, month, and week helpers, roundingIncrement must be omitted or 1.

⚠️ The day and smaller roundTo* helpers are exported as codemod targets, not as recommended hand-written API. In application code, prefer native Temporal .round() directly:

dateTime.round({ smallestUnit: 'day' })
time.round({ smallestUnit: 'minute', roundingMode: 'ceil' })
instant.round({ smallestUnit: 'second' })
import { roundToMonth, roundToWeek, roundToYear } from 'temporal-utils'

const dateTime = Temporal.PlainDateTime.from('2024-07-20T12:30:00')

roundToYear(dateTime).toString()
// '2025-01-01T00:00:00'

roundToMonth(dateTime, 'floor').toString()
// '2024-07-01T00:00:00'

roundToWeek(dateTime, { roundingMode: 'floor' }).toString()
// '2024-07-15T00:00:00'

roundToYear

Signature:

function roundToYear<
  T extends
    | Temporal.PlainYearMonth
    | Temporal.PlainDate
    | Temporal.PlainDateTime
    | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Rounds to the nearest year boundary. Supported input types are Temporal.PlainYearMonth, Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

roundToMonth

Signature:

function roundToMonth<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Rounds to the nearest month boundary. Supported input types are Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

roundToWeek

Signature:

function roundToWeek<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Rounds to the nearest ISO week boundary. Supported input types are Temporal.PlainDate, Temporal.PlainDateTime, and Temporal.ZonedDateTime.

⚠️ roundToDay

Signature:

function roundToDay<T extends Temporal.PlainDateTime | Temporal.ZonedDateTime>(
  date: T,
  options?: RoundingMode | RoundingMathOptions,
): T

Codemod target for rounding to the nearest day. Prefer dateTime.round({ smallestUnit: 'day' }) in hand-written code.

⚠️ roundToHour

Signature:

function roundToHour<
  T extends Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Codemod target for rounding to the nearest hour. Prefer value.round({ smallestUnit: 'hour' }) in hand-written code.

⚠️ roundToMinute

Signature:

function roundToMinute<
  T extends Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Codemod target for rounding to the nearest minute. Prefer value.round({ smallestUnit: 'minute' }) in hand-written code.

⚠️ roundToSecond

Signature:

function roundToSecond<
  T extends Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Codemod target for rounding to the nearest second. Prefer value.round({ smallestUnit: 'second' }) in hand-written code.

⚠️ roundToMillisecond

Signature:

function roundToMillisecond<
  T extends Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Codemod target for rounding to the nearest millisecond. Prefer value.round({ smallestUnit: 'millisecond' }) in hand-written code.

⚠️ roundToMicrosecond

Signature:

function roundToMicrosecond<
  T extends Temporal.Instant | Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T, options?: RoundingMode | RoundingMathOptions): T

Codemod target for rounding to the nearest microsecond. Prefer value.round({ smallestUnit: 'microsecond' }) in hand-written code.

Start Of Unit

Start helpers truncate smaller fields to the beginning of the named unit. startOfWeek uses ISO weeks, so the week starts on Monday.

For Temporal.ZonedDateTime, these helpers use Temporal's own field replacement behavior. If local midnight is skipped by a time-zone transition, Temporal resolves to the first real instant after the skipped wall time.

import { startOfMonth, startOfWeek } from 'temporal-utils'

const zdt = Temporal.ZonedDateTime.from('2024-07-20T12:30:00[America/New_York]')

startOfMonth(zdt).toString()
// '2024-07-01T00:00:00-04:00[America/New_York]'

startOfWeek(zdt).toString()
// '2024-07-15T00:00:00-04:00[America/New_York]'

startOfYear

Signature:

function startOfYear<
  T extends
    | Temporal.PlainYearMonth
    | Temporal.PlainDate
    | Temporal.PlainDateTime
    | Temporal.ZonedDateTime,
>(date: T): T

Returns the start of the current year. For Temporal.PlainYearMonth, this is January of the same year.

startOfMonth

Signature:

function startOfMonth<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the start of the current month.

startOfWeek

Signature:

function startOfWeek<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the start of the current ISO week, which is Monday.

startOfDay

Signature:

function startOfDay<T extends Temporal.PlainDateTime | Temporal.ZonedDateTime>(
  dateTime: T,
): T

Returns midnight at the start of the current day.

startOfHour

Signature:

function startOfHour<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(dateTime: T): T

Returns the start of the current hour.

startOfMinute

Signature:

function startOfMinute<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(dateTime: T): T

Returns the start of the current minute.

startOfSecond

Signature:

function startOfSecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(dateTime: T): T

Returns the start of the current second.

startOfMillisecond

Signature:

function startOfMillisecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(dateTime: T): T

Returns the start of the current millisecond.

startOfMicrosecond

Signature:

function startOfMicrosecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(dateTime: T): T

Returns the start of the current microsecond.

End Of Unit

End helpers return the last representable value before the next unit begins. For date-time and zoned date-time values, this means one nanosecond before the exclusive end. For date-only values, it means one day before the exclusive end. For Temporal.PlainYearMonth, endOfYear returns December of the same year.

import { endOfDay, endOfMonth } from 'temporal-utils'

const dateTime = Temporal.PlainDateTime.from('2024-07-20T12:30:00')

endOfDay(dateTime).toString()
// '2024-07-20T23:59:59.999999999'

endOfMonth(dateTime).toString()
// '2024-07-31T23:59:59.999999999'

endOfYear

Signature:

function endOfYear<
  T extends
    | Temporal.PlainYearMonth
    | Temporal.PlainDate
    | Temporal.PlainDateTime
    | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current year.

endOfMonth

Signature:

function endOfMonth<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current month.

endOfWeek

Signature:

function endOfWeek<
  T extends Temporal.PlainDate | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current ISO week.

endOfDay

Signature:

function endOfDay<T extends Temporal.PlainDateTime | Temporal.ZonedDateTime>(
  date: T,
): T

Returns the last representable value in the current day.

endOfHour

Signature:

function endOfHour<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current hour.

endOfMinute

Signature:

function endOfMinute<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current minute.

endOfSecond

Signature:

function endOfSecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current second.

endOfMillisecond

Signature:

function endOfMillisecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current millisecond.

endOfMicrosecond

Signature:

function endOfMicrosecond<
  T extends Temporal.PlainTime | Temporal.PlainDateTime | Temporal.ZonedDateTime,
>(date: T): T

Returns the last representable value in the current microsecond.

Shared Types

RoundingMode

Type:

import type { RoundingMode } from 'temporal-utils'

RoundingMode is shared by the rounding and difference helpers.

RoundingMathOptions

Type:

import type { RoundingMathOptions } from 'temporal-utils'

RoundingMathOptions contains the rounding fields used by single-unit math helpers.

The unit is implied by the helper name. For example, roundToWeek(date, options) forces smallestUnit: 'week' internally, and diffMonths(date0, date1, options) forces month-based difference math internally.