date
Pure date and time helpers used by DatePicker. None of them read the current clock, and Date values are read in the local time zone. The two conversion helpers also bridge to @internationalized/date, the library DatePicker builds on.
Conversion
dateToValue(d)
function dateToValue(d: Date): CalendarDateConverts a JavaScript Date to an @internationalized/date CalendarDate, keeping the local year, month, and day and dropping the time.
| Parameter | Type | Description |
|---|---|---|
d | Date | The date to convert. Time-of-day is ignored. |
Returns: CalendarDate (month is 1-based).
import { dateToValue } from '@myghf/ui'
const value = dateToValue(new Date(2026, 7, 15, 23, 59))
// value.year === 2026, value.month === 8, value.day === 15valueToDate(v)
function valueToDate(v: DateValue): DateConverts an @internationalized/date value back to a JavaScript Date. A CalendarDateTime is resolved in the local time zone (keeping its time); a date-only value becomes local midnight.
| Parameter | Type | Description |
|---|---|---|
v | DateValue | A CalendarDate or CalendarDateTime. |
Returns: Date.
import { CalendarDateTime } from '@internationalized/date'
import { dateToValue, valueToDate } from '@myghf/ui'
const roundTrip = valueToDate(dateToValue(new Date(2026, 7, 15)))
// → a local Date for 2026-08-15
valueToDate(new CalendarDateTime(2026, 8, 15, 9, 30)).getHours()
// → 9Installing the types
@internationalized/date ships as a dependency of @myghf/ui, so these helpers work out of the box. If you annotate your own CalendarDate/DateValue variables, import the types from @internationalized/date in your app.
ISO strings
toISODate(d)
function toISODate(d: Date): stringFormats a Date as a zero-padded YYYY-MM-DD string, using local date parts. It is nottoISOString(), so it does not shift to UTC.
| Parameter | Type | Description |
|---|---|---|
d | Date | The date to format. |
Returns: string in YYYY-MM-DD form.
import { toISODate } from '@myghf/ui'
toISODate(new Date(2026, 2, 5)) // → '2026-03-05'toTime(minutes)
function toTime(minutes: number): stringFormats a number of minutes since midnight as a zero-padded HH:MM string.
| Parameter | Type | Description |
|---|---|---|
minutes | number | Minutes since midnight. |
Returns: string in HH:MM form. The value is not wrapped modulo 24, so 1440 formats as '24:00'.
import { toTime } from '@myghf/ui'
toTime(0) // → '00:00'
toTime(545) // → '09:05'toMinutes(time)
function toMinutes(time: string): numberParses an HH:MM string into minutes since midnight. A missing minute part (for example '09') is treated as 0, and a non-numeric minute part also becomes 0 (the m || 0 fallback). A non-numeric hour makes the whole result NaN.
| Parameter | Type | Description |
|---|---|---|
time | string | A time in HH:MM form. |
Returns: number of minutes since midnight.
import { toMinutes } from '@myghf/ui'
toMinutes('09:05') // → 545
toMinutes('09') // → 540Time on a date
clampTime(d, time)
function clampTime(d: Date, time: string): DateReturns a new Date copied from d with the hours and minutes taken from time and the seconds and milliseconds zeroed. d is not mutated.
| Parameter | Type | Description |
|---|---|---|
d | Date | The source date; its year, month, and day are kept. |
time | string | The time to apply, in HH:MM form. |
Returns: a new Date.
import { clampTime } from '@myghf/ui'
const out = clampTime(new Date(2026, 7, 15, 23, 59, 59), '08:30')
// out.getHours() === 8, out.getMinutes() === 30, out.getSeconds() === 0Ranges
sortRange(a, b)
function sortRange(a: Date, b: Date): [Date, Date]
function sortRange(a: Date | null, b: Date | null): [Date | null, Date | null]Orders a pair of dates ascending by timestamp. If either value is null, the pair is returned unchanged ([a, b]) rather than partially sorted, so a half-filled range keeps its shape.
| Parameter | Type | Description |
|---|---|---|
a | Date | null | First endpoint. |
b | Date | null | Second endpoint. |
Returns: a [start, end] tuple, ascending when both are present.
import { sortRange } from '@myghf/ui'
sortRange(new Date(2026, 1, 5), new Date(2026, 1, 1))
// → [2026-02-01, 2026-02-05]
sortRange(new Date(2026, 1, 5), null)
// → [2026-02-05, null] (unchanged)Option builders
buildHourOptions(hourFormat)
function buildHourOptions(hourFormat: '12' | '24'): number[]Builds the hour list for a picker. '24' returns 0–23; '12' returns 1–12.
| Parameter | Type | Description |
|---|---|---|
hourFormat | '12' | '24' | Which clock the options target. |
Returns: number[] — 24 entries for '24', 12 for '12'.
import { buildHourOptions } from '@myghf/ui'
buildHourOptions('24')[0] // → 0
buildHourOptions('12')[0] // → 1
buildHourOptions('12').length // → 12buildMinuteOptions(minuteStep)
function buildMinuteOptions(minuteStep: number): number[]Builds the minute list from 0 up to (but not including) 60 in increments of minuteStep. A non-finite or non-positive step falls back to 1, so the list is never empty.
| Parameter | Type | Description |
|---|---|---|
minuteStep | number | Increment in minutes. Values <= 0 or non-finite become 1. |
Returns: number[] of minutes.
import { buildMinuteOptions } from '@myghf/ui'
buildMinuteOptions(15) // → [0, 15, 30, 45]
buildMinuteOptions(7) // → [0, 7, 14, 21, 28, 35, 42, 49, 56]
buildMinuteOptions(0) // → every minute (step falls back to 1)12/24-hour conversion
to12Hour(hour24)
function to12Hour(hour24: number): { hour: number; meridiem: 'am' | 'pm' }Converts a 24-hour hour to its 12-hour representation. The input is reduced modulo 24 first, so out-of-range and negative values are handled (-1 → 11 pm).
| Parameter | Type | Description |
|---|---|---|
hour24 | number | Hour on the 24-hour clock; any integer is accepted. |
Returns: { hour: number; meridiem: 'am' \| 'pm' }, with hour in 1–12.
import { to12Hour } from '@myghf/ui'
to12Hour(0) // → { hour: 12, meridiem: 'am' }
to12Hour(9) // → { hour: 9, meridiem: 'am' }
to12Hour(13) // → { hour: 1, meridiem: 'pm' }from12Hour(hour, meridiem)
function from12Hour(hour: number, meridiem: 'am' | 'pm'): numberThe inverse of to12Hour: converts a 12-hour hour plus meridiem back to the 24-hour clock. Unlike to12Hour, which uses a true modulo, this helper uses a signed remainder (Math.trunc(hour) % 12). Non-negative hours behave as expected; a negative hour keeps a negative remainder, so from12Hour(-1, 'pm') is 11, not 13.
| Parameter | Type | Description |
|---|---|---|
hour | number | Hour on the 12-hour clock; truncated, then taken as a signed remainder of 12. |
meridiem | 'am' | 'pm' | 'pm' adds twelve hours. |
Returns: number on the 24-hour clock (0–23) for non-negative inputs.
import { from12Hour } from '@myghf/ui'
from12Hour(12, 'am') // → 0
from12Hour(12, 'pm') // → 12
from12Hour(1, 'pm') // → 13
from12Hour(-1, 'pm') // → 11 (signed remainder: -1 + 12)