useDateFormatter
Date formatting and manipulation utilities built on @internationalized/date.
Usage
Use the auto-imported useDateFormatter composable for date formatting, conversion and manipulation, built on the @internationalized/date library for internationalized date handling.
<script setup lang="ts">
const formatter = useDateFormatter({ locale: 'en-US' })
const today = formatter.getToday()
const formattedDate = formatter.format(today)
// "Nov 29, 2025"
const isoString = formatter.toISO(today)
// "2025-11-29"
</script>
useDateFormatterprovides locale-aware date formatting based onIntl.DateTimeFormat.- Supports bulk conversion of single dates, date ranges, date arrays and nested objects.
- Specify a timezone via the
timeZoneoption (defaults to the local timezone); identifiers follow the IANA timezone database specification.
All formatting and conversion methods have built-in error handling: passing
null or undefined returns an empty string or null without throwing an exception.Capabilities at a Glance
The table below covers the output shapes of useDateFormatter across common date scenarios:
当前 locale: zh-CN · timeZone: UTC
| 调用 | 返回值 |
|---|---|
format(today) | 2026年6月29日 |
toISO(today) | 2026-06-29 |
toTimestamp(today) | 1782691200000 |
toUnixTimestamp(today) | 1782691200 |
isWeekend(today) | false |
isWeekday(today) | true |
isToday(today) | true |
getDayOfWeek(today) | 0 |
getDayOfWeekName(today, "long") | 星期一 |
getDayOfWeekName(today, "short") | 周一 |
getStartOfMonth(today) | 2026-06-01 |
getEndOfMonth(today) | 2026-06-30 |
getStartOfYear(today) | 2026-01-01 |
getEndOfYear(today) | 2026-12-31 |
formatRange(start, end) | 2026年6月29日 - 2026年7月6日 |
formatArray([d, d+1, d+2]) | 2026年6月29日, 2026年6月30日, 2026年7月1日 |
parse("2026-01-01")?.toString() | 2026-01-01 |
<script setup lang="ts">
const f = useDateFormatter({ locale: 'zh-CN' })
const today = f.getToday()
const range = { start: today, end: today.add({ days: 7 }) }
const list = [today, today.add({ days: 1 }), today.add({ days: 2 })]
const rows = [
{ method: 'format(today)', value: f.format(today) },
{ method: 'toISO(today)', value: f.toISO(today) },
{ method: 'toTimestamp(today)', value: f.toTimestamp(today) },
{ method: 'toUnixTimestamp(today)', value: f.toUnixTimestamp(today) },
{ method: 'isWeekend(today)', value: f.isWeekend(today) },
{ method: 'isWeekday(today)', value: f.isWeekday(today) },
{ method: 'isToday(today)', value: f.isToday(today) },
{ method: 'getDayOfWeek(today)', value: f.getDayOfWeek(today) },
{ method: 'getDayOfWeekName(today, "long")', value: f.getDayOfWeekName(today, 'long') },
{ method: 'getDayOfWeekName(today, "short")', value: f.getDayOfWeekName(today, 'short') },
{ method: 'getStartOfMonth(today)', value: f.toISO(f.getStartOfMonth(today)) },
{ method: 'getEndOfMonth(today)', value: f.toISO(f.getEndOfMonth(today)) },
{ method: 'getStartOfYear(today)', value: f.toISO(f.getStartOfYear(today)) },
{ method: 'getEndOfYear(today)', value: f.toISO(f.getEndOfYear(today)) },
{ method: 'formatRange(start, end)', value: f.formatRange(range.start, range.end) },
{ method: 'formatArray([d, d+1, d+2])', value: f.formatArray(list) },
{ method: 'parse("2026-01-01")?.toString()', value: f.parse('2026-01-01')?.toString() ?? 'null' }
]
const columns = [
{ accessorKey: 'method', header: '调用' },
{ accessorKey: 'value', header: '返回值' }
]
</script>
<template>
<div class="flex flex-col gap-3">
<p class="text-xs text-muted">
当前 locale: {{ f.locale }} · timeZone: {{ f.timeZone }}
</p>
<MDataTable :columns="columns" :data="rows" stripe bordered density="compact" />
</div>
</template>
Integration with AutoForm
When using date fields in AutoForm, use convertToISO() for bulk conversion before submitting:
<script setup lang="ts">
const { afz } = useAutoForm()
const formatter = useDateFormatter()
const schema = afz.object({
eventDate: afz.calendarDate(),
eventRange: afz.calendarDate({
controlProps: { mode: 'range' }
})
})
const formData = ref()
async function handleSubmit() {
// Automatically handle conversion for all date fields
const payload = formatter.convertToISO(formData.value)
// payload.eventDate: "2025-11-29"
// payload.eventRange: { start: "2025-11-01", end: "2025-11-30" }
await api.submit(payload)
}
</script>
convertToISO automatically traverses all nested date fields while preserving the object structure — no manual conversion required.API
useDateFormatter()
useDateFormatter(options?: DateFormatterOptions): DateFormatter
Creates a date formatter instance.
Parameters
options
DateFormatterOptions
Date formatter configuration options.
locale
string
Locale. Defaults to
'zh-CN'.formatOptions
Intl.DateTimeFormatOptions
Date format options, following the Intl.DateTimeFormat specification. Defaults to
{ dateStyle: 'medium' }.timeZone
string
Timezone identifier (e.g.
'Asia/Shanghai', 'America/New_York'). Defaults to the local timezone. See the @internationalized/date timezone docs.Returns
Returns a date formatter object with the following methods and properties.
Formatting Methods
format()
(date: DateValue | undefined | null) => string
Format a single date as a localized string.
formatter.format(date)
// "Nov 29, 2025"
formatRange()
(start: DateValue | undefined | null, end: DateValue | undefined | null, separator?: string) => string
Format a date range. Default separator is
' - '.formatter.formatRange(startDate, endDate)
// "Nov 1, 2025 - Nov 30, 2025"
formatter.formatRange(startDate, endDate, ' to ')
// "Nov 1, 2025 to Nov 30, 2025"
formatArray()
(dates: DateValue[] | undefined | null, separator?: string) => string
Format an array of dates. Default separator is
', '.formatter.formatArray([date1, date2, date3])
// "Nov 1, 2025, Nov 15, 2025, Nov 29, 2025"
Conversion Methods
toISO()
(date: DateValue | undefined | null) => string
Convert to an ISO 8601 string.
formatter.toISO(date)
// "2025-11-29"
toDate()
(date: DateValue | undefined | null) => Date | null
Convert to a JavaScript Date object.
toTimestamp()
(date: DateValue | undefined | null) => number | null
Convert to a timestamp (milliseconds).
formatter.toTimestamp(date)
// 1732838400000
toUnixTimestamp()
(date: DateValue | undefined | null) => number | null
Convert to a Unix timestamp (seconds).
formatter.toUnixTimestamp(date)
// 1732838400
parse()
(value: string) => DateValue | null
Parse an ISO 8601 date string. Automatically identifies
CalendarDate, CalendarDateTime or ZonedDateTime.formatter.parse('2025-11-29')
// CalendarDate
formatter.parse('2025-11-29T10:30:00')
// CalendarDateTime
formatter.parse('2025-11-29T10:30:00[Asia/Shanghai]')
// ZonedDateTime
Utility Methods — Getting Dates
getToday()
() => CalendarDate
Get today's date.
getNow()
() => ZonedDateTime
Get the current date and time.
getStartOfWeek()
(date: DateValue) => DateValue
Get the start of the week (based on the current locale).
getEndOfWeek()
(date: DateValue) => DateValue
Get the end of the week (based on the current locale).
getStartOfMonth()
(date: DateValue) => DateValue
Get the start of the month.
getEndOfMonth()
(date: DateValue) => DateValue
Get the end of the month.
getStartOfYear()
(date: DateValue) => DateValue
Get the start of the year.
getEndOfYear()
(date: DateValue) => DateValue
Get the end of the year.
Utility Methods — Queries
getDayOfWeek()
(date: DateValue) => number
Get the day of the week as a number (0–6, where 0 is the localized first day of the week).
getDayOfWeekName()
(date: DateValue, style?: 'narrow' | 'short' | 'long') => string
Get the localized name of the day of the week.
Parameters
date
DateValue required
Date object.
style
'narrow' | 'short' | 'long'
Format style. Defaults to
long.'narrow'— Shortest format, e.g. "M"'short'— Short format, e.g. "Mon"'long'— Full format, e.g. "Monday"
const date = formatter.getToday()
formatter.getDayOfWeekName(date, 'narrow') // "M"
formatter.getDayOfWeekName(date, 'short') // "Mon"
formatter.getDayOfWeekName(date, 'long') // "Monday"
formatter.getDayOfWeekName(date) // "Monday" (default)
getWeeksInMonth()
(date: DateValue) => number
Get the number of weeks in the month.
isWeekday()
(date: DateValue) => boolean
Check whether the date is a weekday.
isWeekend()
(date: DateValue) => boolean
Check whether the date is a weekend day.
isSameDay()
(a: DateValue, b: DateValue) => boolean
Check whether two dates are the same day.
isSameMonth()
(a: DateValue, b: DateValue) => boolean
Check whether two dates are in the same month.
isSameYear()
(a: DateValue, b: DateValue) => boolean
Check whether two dates are in the same year.
isToday()
(date: DateValue) => boolean
Check whether the date is today.
isDateValue()
(value: unknown) => value is DateValue
Type guard: check whether a value is a
DateValue.isDateRange()
(value: unknown) => value is DateRange
Type guard: check whether a value is a
DateRange.Bulk Conversion Methods
convertData()
<T>(data: T, converter: (value: DateValue) => any) => T
Generic data conversion function. Automatically handles single dates, date ranges, date arrays and nested objects.
const converted = formatter.convertData(complexData, formatter.toISO)
convertToISO()
<T>(data: T) => T
Bulk convert to ISO strings. Supports single dates, date ranges, arrays and nested objects.
// Single date
formatter.convertToISO(date)
// "2025-11-29"
// Date range
formatter.convertToISO({ start: date1, end: date2 })
// { start: "2025-11-01", end: "2025-11-30" }
// Date array
formatter.convertToISO([date1, date2])
// ["2025-11-01", "2025-11-15"]
// Nested object
formatter.convertToISO({
createdAt: date1,
range: { start: date2, end: date3 }
})
// {
// createdAt: "2025-11-01",
// range: { start: "2025-11-20", end: "2025-11-29" }
// }
convertToFormatted()
<T>(data: T) => T
Bulk convert to formatted strings.
convertToDate()
<T>(data: T) => T
Bulk convert to Date objects.
Configuration Properties
locale
string
The current locale in use.
timeZone
string
The current timezone in use.
Changelog
No recent changes