Internationalized calendar, date, and time manipulation utilities with support for 13 international calendar systems
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Internationalized date formatting with cross-browser compatibility and comprehensive format options.
Internationalized date formatting with browser bug fixes and polyfills, providing a consistent API across different environments.
/**
* Wrapper around Intl.DateTimeFormat with browser bug fixes and polyfills
*/
class DateFormatter {
/**
* Creates a new DateFormatter instance
* @param locale - Locale identifier (e.g., 'en-US', 'de-DE', 'ja-JP')
* @param options - Intl.DateTimeFormat options for formatting
*/
constructor(locale: string, options?: Intl.DateTimeFormatOptions);
/**
* Formats date as string
* @param date - JavaScript Date object to format
* @returns Formatted date string according to locale and options
*/
format(date: Date): string;
/**
* Formats to array of parts
* @param date - JavaScript Date object to format
* @returns Array of formatted parts with type and value
*/
formatToParts(date: Date): Intl.DateTimeFormatPart[];
/**
* Formats date range
* @param start - Start JavaScript Date of range
* @param end - End JavaScript Date of range
* @returns Formatted date range string
*/
formatRange(start: Date, end: Date): string;
/**
* Formats range to parts
* @param start - Start JavaScript Date of range
* @param end - End JavaScript Date of range
* @returns Array of formatted range parts with source indicators
*/
formatRangeToParts(start: Date, end: Date): Intl.DateTimeFormatRangePart[];
/**
* Returns resolved formatting options
* @returns Resolved Intl.DateTimeFormat options
*/
resolvedOptions(): Intl.ResolvedDateTimeFormatOptions;
}Usage Examples:
import { DateFormatter, CalendarDate, CalendarDateTime } from "@internationalized/date";
const date = new CalendarDate(2024, 3, 15);
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 0);
// Convert to JavaScript Date objects for formatting
const jsDate = date.toDate('UTC');
const jsDateTime = dateTime.toDate('UTC');
// Basic formatting in different locales
const usFormatter = new DateFormatter('en-US');
const deFormatter = new DateFormatter('de-DE');
const jaFormatter = new DateFormatter('ja-JP');
const usFormat = usFormatter.format(jsDate); // "3/15/2024"
const deFormat = deFormatter.format(jsDate); // "15.3.2024"
const jaFormat = jaFormatter.format(jsDate); // "2024/3/15"Comprehensive formatting options for controlling date and time display.
Date Formatting Options:
import { DateFormatter, CalendarDate } from "@internationalized/date";
const date = new CalendarDate(2024, 3, 15);
const jsDate = date.toDate('UTC');
// Different date styles
const shortDate = new DateFormatter('en-US', { dateStyle: 'short' });
const mediumDate = new DateFormatter('en-US', { dateStyle: 'medium' });
const longDate = new DateFormatter('en-US', { dateStyle: 'long' });
const fullDate = new DateFormatter('en-US', { dateStyle: 'full' });
console.log(shortDate.format(jsDate)); // "3/15/24"
console.log(mediumDate.format(jsDate)); // "Mar 15, 2024"
console.log(longDate.format(jsDate)); // "March 15, 2024"
console.log(fullDate.format(jsDate)); // "Friday, March 15, 2024"
// Custom date components
const customDate = new DateFormatter('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
});
console.log(customDate.format(jsDate)); // "Friday, March 15, 2024"Time Formatting Options:
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
const jsDateTime = dateTime.toDate('UTC');
// Different time styles
const shortTime = new DateFormatter('en-US', { timeStyle: 'short' });
const mediumTime = new DateFormatter('en-US', { timeStyle: 'medium' });
const longTime = new DateFormatter('en-US', { timeStyle: 'long' });
console.log(shortTime.format(jsDateTime)); // "2:30 PM"
console.log(mediumTime.format(jsDateTime)); // "2:30:45 PM"
console.log(longTime.format(jsDateTime)); // "2:30:45 PM GMT"
// Custom time components
const customTime = new DateFormatter('en-US', {
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: false
});
console.log(customTime.format(jsDateTime)); // "14:30:45"Combined Date and Time Formatting:
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
const jsDateTime = dateTime.toDate('UTC');
// Combined styles
const shortDateTime = new DateFormatter('en-US', {
dateStyle: 'short',
timeStyle: 'short'
});
console.log(shortDateTime.format(jsDateTime)); // "3/15/24, 2:30 PM"
// Custom combined format
const customDateTime = new DateFormatter('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
hour12: true
});
console.log(customDateTime.format(jsDateTime)); // "Mar 15, 2024, 2:30 PM"Access individual parts of formatted dates for custom styling and layout.
interface Intl.DateTimeFormatPart {
type: string;
value: string;
}Usage Examples:
import { DateFormatter, CalendarDate } from "@internationalized/date";
const date = new CalendarDate(2024, 3, 15);
const jsDate = date.toDate('UTC');
const formatter = new DateFormatter('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
const parts = formatter.formatToParts(jsDate);
// [
// { type: 'month', value: 'March' },
// { type: 'literal', value: ' ' },
// { type: 'day', value: '15' },
// { type: 'literal', value: ', ' },
// { type: 'year', value: '2024' }
// ]
// Use parts for custom formatting
const customFormat = parts
.map(part => {
if (part.type === 'month') {
return `<strong>${part.value}</strong>`;
} else if (part.type === 'day') {
return `<em>${part.value}</em>`;
}
return part.value;
})
.join('');
// "<strong>March</strong> <em>15</em>, 2024"Format date ranges with appropriate connectors and shared components.
import { DateFormatter, CalendarDate } from "@internationalized/date";
const startDate = new CalendarDate(2024, 3, 15);
const endDate = new CalendarDate(2024, 3, 20);
const endDateDifferentMonth = new CalendarDate(2024, 4, 10);
const endDateDifferentYear = new CalendarDate(2025, 2, 28);
// Convert to JavaScript Date objects
const jsStartDate = startDate.toDate('UTC');
const jsEndDate = endDate.toDate('UTC');
const jsEndDateDifferentMonth = endDateDifferentMonth.toDate('UTC');
const jsEndDateDifferentYear = endDateDifferentYear.toDate('UTC');
const formatter = new DateFormatter('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
// Same month range
const sameMonth = formatter.formatRange(jsStartDate, jsEndDate);
console.log(sameMonth); // "Mar 15 – 20, 2024"
// Different month range
const diffMonth = formatter.formatRange(jsStartDate, jsEndDateDifferentMonth);
console.log(diffMonth); // "Mar 15 – Apr 10, 2024"
// Different year range
const diffYear = formatter.formatRange(jsStartDate, jsEndDateDifferentYear);
console.log(diffYear); // "Mar 15, 2024 – Feb 28, 2025"Range Parts for Custom Styling:
import { DateFormatter, CalendarDate } from "@internationalized/date";
const startDate = new CalendarDate(2024, 3, 15);
const endDate = new CalendarDate(2024, 4, 10);
// Convert to JavaScript Date objects
const jsStartDate = startDate.toDate('UTC');
const jsEndDate = endDate.toDate('UTC');
const formatter = new DateFormatter('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
const rangeParts = formatter.formatRangeToParts(jsStartDate, jsEndDate);
// [
// { type: 'month', value: 'Mar', source: 'startRange' },
// { type: 'literal', value: ' ', source: 'startRange' },
// { type: 'day', value: '15', source: 'startRange' },
// { type: 'literal', value: ' – ', source: 'shared' },
// { type: 'month', value: 'Apr', source: 'endRange' },
// { type: 'literal', value: ' ', source: 'endRange' },
// { type: 'day', value: '10', source: 'endRange' },
// { type: 'literal', value: ', ', source: 'shared' },
// { type: 'year', value: '2024', source: 'shared' }
// ]Examples of formatting behavior across different locales and calendar systems.
Different Locale Conventions:
import { DateFormatter, CalendarDate } from "@internationalized/date";
const date = new CalendarDate(2024, 3, 15);
const jsDate = date.toDate('UTC');
// US format (month/day/year)
const usFormatter = new DateFormatter('en-US');
console.log(usFormatter.format(jsDate)); // "3/15/2024"
// European format (day/month/year)
const ukFormatter = new DateFormatter('en-GB');
console.log(ukFormatter.format(jsDate)); // "15/03/2024"
// German format (day.month.year)
const deFormatter = new DateFormatter('de-DE');
console.log(deFormatter.format(jsDate)); // "15.3.2024"
// Japanese format (year/month/day)
const jaFormatter = new DateFormatter('ja-JP');
console.log(jaFormatter.format(jsDate)); // "2024/3/15"
// Arabic format (right-to-left)
const arFormatter = new DateFormatter('ar-SA');
console.log(arFormatter.format(jsDate)); // "١٥/٣/٢٠٢٤"Calendar System Formatting:
import {
DateFormatter,
CalendarDate,
createCalendar
} from "@internationalized/date";
// Gregorian date
const gregorianDate = new CalendarDate(2024, 3, 15);
// Buddhist date (same absolute date)
const buddhistDate = new CalendarDate(createCalendar('buddhist'), 2567, 3, 15);
// Japanese date with era
const japaneseDate = new CalendarDate(createCalendar('japanese'), 'reiwa', 6, 3, 15);
// Convert to JavaScript Date objects
const jsGregorianDate = gregorianDate.toDate('UTC');
const jsBuddhistDate = buddhistDate.toDate('UTC');
const jsJapaneseDate = japaneseDate.toDate('UTC');
// Format in appropriate locales
const gregorianFormatter = new DateFormatter('en-US');
const buddhistFormatter = new DateFormatter('th-TH', { calendar: 'buddhist' });
const japaneseFormatter = new DateFormatter('ja-JP', { calendar: 'japanese' });
console.log(gregorianFormatter.format(jsGregorianDate)); // "3/15/2024"
console.log(buddhistFormatter.format(jsBuddhistDate)); // "15/3/2567"
console.log(japaneseFormatter.format(jsJapaneseDate)); // "R6/3/15" (Reiwa 6)Comprehensive formatting options for specialized use cases.
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
const jsDateTime = dateTime.toDate('UTC');
// Number formatting options
const leadingZeros = new DateFormatter('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
console.log(leadingZeros.format(jsDateTime)); // "03/15/2024, 02:30:45 PM"
// Text representation options
const textFormat = new DateFormatter('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: 'numeric',
minute: '2-digit',
timeZoneName: 'short'
});
console.log(textFormat.format(jsDateTime)); // "Friday, March 15, 2024 at 2:30 PM UTC"
// Hour cycle options
const hour24 = new DateFormatter('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: false
});
console.log(hour24.format(jsDateTime)); // "14:30"
const hour12 = new DateFormatter('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true
});
console.log(hour12.format(jsDateTime)); // "2:30 PM"To use the DateFormatter with @internationalized/date objects, you must first convert them to JavaScript Date objects using the toDate() method:
import { DateFormatter, CalendarDate, ZonedDateTime } from "@internationalized/date";
const calendarDate = new CalendarDate(2024, 3, 15);
const zonedDateTime = new ZonedDateTime(2024, 3, 15, 'America/New_York', -5 * 60 * 60 * 1000, 14, 30);
// Convert to JavaScript Date objects
const jsDate = calendarDate.toDate('UTC');
const jsZonedDate = zonedDateTime.toDate(); // Already timezone-aware
// Format with DateFormatter
const formatter = new DateFormatter('en-US');
console.log(formatter.format(jsDate));
console.log(formatter.format(jsZonedDate));