0
# Date Formatting
1
2
Internationalized date formatting with cross-browser compatibility and comprehensive format options.
3
4
## Capabilities
5
6
### DateFormatter Class
7
8
Internationalized date formatting with browser bug fixes and polyfills, providing a consistent API across different environments.
9
10
```typescript { .api }
11
/**
12
* Wrapper around Intl.DateTimeFormat with browser bug fixes and polyfills
13
*/
14
class DateFormatter {
15
/**
16
* Creates a new DateFormatter instance
17
* @param locale - Locale identifier (e.g., 'en-US', 'de-DE', 'ja-JP')
18
* @param options - Intl.DateTimeFormat options for formatting
19
*/
20
constructor(locale: string, options?: Intl.DateTimeFormatOptions);
21
22
/**
23
* Formats date as string
24
* @param date - JavaScript Date object to format
25
* @returns Formatted date string according to locale and options
26
*/
27
format(date: Date): string;
28
29
/**
30
* Formats to array of parts
31
* @param date - JavaScript Date object to format
32
* @returns Array of formatted parts with type and value
33
*/
34
formatToParts(date: Date): Intl.DateTimeFormatPart[];
35
36
/**
37
* Formats date range
38
* @param start - Start JavaScript Date of range
39
* @param end - End JavaScript Date of range
40
* @returns Formatted date range string
41
*/
42
formatRange(start: Date, end: Date): string;
43
44
/**
45
* Formats range to parts
46
* @param start - Start JavaScript Date of range
47
* @param end - End JavaScript Date of range
48
* @returns Array of formatted range parts with source indicators
49
*/
50
formatRangeToParts(start: Date, end: Date): Intl.DateTimeFormatRangePart[];
51
52
/**
53
* Returns resolved formatting options
54
* @returns Resolved Intl.DateTimeFormat options
55
*/
56
resolvedOptions(): Intl.ResolvedDateTimeFormatOptions;
57
}
58
```
59
60
**Usage Examples:**
61
62
```typescript
63
import { DateFormatter, CalendarDate, CalendarDateTime } from "@internationalized/date";
64
65
const date = new CalendarDate(2024, 3, 15);
66
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 0);
67
68
// Convert to JavaScript Date objects for formatting
69
const jsDate = date.toDate('UTC');
70
const jsDateTime = dateTime.toDate('UTC');
71
72
// Basic formatting in different locales
73
const usFormatter = new DateFormatter('en-US');
74
const deFormatter = new DateFormatter('de-DE');
75
const jaFormatter = new DateFormatter('ja-JP');
76
77
const usFormat = usFormatter.format(jsDate); // "3/15/2024"
78
const deFormat = deFormatter.format(jsDate); // "15.3.2024"
79
const jaFormat = jaFormatter.format(jsDate); // "2024/3/15"
80
```
81
82
### Formatting Options
83
84
Comprehensive formatting options for controlling date and time display.
85
86
**Date Formatting Options:**
87
88
```typescript
89
import { DateFormatter, CalendarDate } from "@internationalized/date";
90
91
const date = new CalendarDate(2024, 3, 15);
92
const jsDate = date.toDate('UTC');
93
94
// Different date styles
95
const shortDate = new DateFormatter('en-US', { dateStyle: 'short' });
96
const mediumDate = new DateFormatter('en-US', { dateStyle: 'medium' });
97
const longDate = new DateFormatter('en-US', { dateStyle: 'long' });
98
const fullDate = new DateFormatter('en-US', { dateStyle: 'full' });
99
100
console.log(shortDate.format(jsDate)); // "3/15/24"
101
console.log(mediumDate.format(jsDate)); // "Mar 15, 2024"
102
console.log(longDate.format(jsDate)); // "March 15, 2024"
103
console.log(fullDate.format(jsDate)); // "Friday, March 15, 2024"
104
105
// Custom date components
106
const customDate = new DateFormatter('en-US', {
107
year: 'numeric',
108
month: 'long',
109
day: 'numeric',
110
weekday: 'long'
111
});
112
console.log(customDate.format(jsDate)); // "Friday, March 15, 2024"
113
```
114
115
**Time Formatting Options:**
116
117
```typescript
118
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
119
120
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
121
const jsDateTime = dateTime.toDate('UTC');
122
123
// Different time styles
124
const shortTime = new DateFormatter('en-US', { timeStyle: 'short' });
125
const mediumTime = new DateFormatter('en-US', { timeStyle: 'medium' });
126
const longTime = new DateFormatter('en-US', { timeStyle: 'long' });
127
128
console.log(shortTime.format(jsDateTime)); // "2:30 PM"
129
console.log(mediumTime.format(jsDateTime)); // "2:30:45 PM"
130
console.log(longTime.format(jsDateTime)); // "2:30:45 PM GMT"
131
132
// Custom time components
133
const customTime = new DateFormatter('en-US', {
134
hour: 'numeric',
135
minute: '2-digit',
136
second: '2-digit',
137
hour12: false
138
});
139
console.log(customTime.format(jsDateTime)); // "14:30:45"
140
```
141
142
**Combined Date and Time Formatting:**
143
144
```typescript
145
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
146
147
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
148
const jsDateTime = dateTime.toDate('UTC');
149
150
// Combined styles
151
const shortDateTime = new DateFormatter('en-US', {
152
dateStyle: 'short',
153
timeStyle: 'short'
154
});
155
console.log(shortDateTime.format(jsDateTime)); // "3/15/24, 2:30 PM"
156
157
// Custom combined format
158
const customDateTime = new DateFormatter('en-US', {
159
year: 'numeric',
160
month: 'short',
161
day: 'numeric',
162
hour: 'numeric',
163
minute: '2-digit',
164
hour12: true
165
});
166
console.log(customDateTime.format(jsDateTime)); // "Mar 15, 2024, 2:30 PM"
167
```
168
169
### Format Parts
170
171
Access individual parts of formatted dates for custom styling and layout.
172
173
```typescript { .api }
174
interface Intl.DateTimeFormatPart {
175
type: string;
176
value: string;
177
}
178
```
179
180
**Usage Examples:**
181
182
```typescript
183
import { DateFormatter, CalendarDate } from "@internationalized/date";
184
185
const date = new CalendarDate(2024, 3, 15);
186
const jsDate = date.toDate('UTC');
187
const formatter = new DateFormatter('en-US', {
188
year: 'numeric',
189
month: 'long',
190
day: 'numeric'
191
});
192
193
const parts = formatter.formatToParts(jsDate);
194
// [
195
// { type: 'month', value: 'March' },
196
// { type: 'literal', value: ' ' },
197
// { type: 'day', value: '15' },
198
// { type: 'literal', value: ', ' },
199
// { type: 'year', value: '2024' }
200
// ]
201
202
// Use parts for custom formatting
203
const customFormat = parts
204
.map(part => {
205
if (part.type === 'month') {
206
return `<strong>${part.value}</strong>`;
207
} else if (part.type === 'day') {
208
return `<em>${part.value}</em>`;
209
}
210
return part.value;
211
})
212
.join('');
213
// "<strong>March</strong> <em>15</em>, 2024"
214
```
215
216
### Date Range Formatting
217
218
Format date ranges with appropriate connectors and shared components.
219
220
```typescript
221
import { DateFormatter, CalendarDate } from "@internationalized/date";
222
223
const startDate = new CalendarDate(2024, 3, 15);
224
const endDate = new CalendarDate(2024, 3, 20);
225
const endDateDifferentMonth = new CalendarDate(2024, 4, 10);
226
const endDateDifferentYear = new CalendarDate(2025, 2, 28);
227
228
// Convert to JavaScript Date objects
229
const jsStartDate = startDate.toDate('UTC');
230
const jsEndDate = endDate.toDate('UTC');
231
const jsEndDateDifferentMonth = endDateDifferentMonth.toDate('UTC');
232
const jsEndDateDifferentYear = endDateDifferentYear.toDate('UTC');
233
234
const formatter = new DateFormatter('en-US', {
235
year: 'numeric',
236
month: 'short',
237
day: 'numeric'
238
});
239
240
// Same month range
241
const sameMonth = formatter.formatRange(jsStartDate, jsEndDate);
242
console.log(sameMonth); // "Mar 15 – 20, 2024"
243
244
// Different month range
245
const diffMonth = formatter.formatRange(jsStartDate, jsEndDateDifferentMonth);
246
console.log(diffMonth); // "Mar 15 – Apr 10, 2024"
247
248
// Different year range
249
const diffYear = formatter.formatRange(jsStartDate, jsEndDateDifferentYear);
250
console.log(diffYear); // "Mar 15, 2024 – Feb 28, 2025"
251
```
252
253
**Range Parts for Custom Styling:**
254
255
```typescript
256
import { DateFormatter, CalendarDate } from "@internationalized/date";
257
258
const startDate = new CalendarDate(2024, 3, 15);
259
const endDate = new CalendarDate(2024, 4, 10);
260
261
// Convert to JavaScript Date objects
262
const jsStartDate = startDate.toDate('UTC');
263
const jsEndDate = endDate.toDate('UTC');
264
265
const formatter = new DateFormatter('en-US', {
266
year: 'numeric',
267
month: 'short',
268
day: 'numeric'
269
});
270
271
const rangeParts = formatter.formatRangeToParts(jsStartDate, jsEndDate);
272
// [
273
// { type: 'month', value: 'Mar', source: 'startRange' },
274
// { type: 'literal', value: ' ', source: 'startRange' },
275
// { type: 'day', value: '15', source: 'startRange' },
276
// { type: 'literal', value: ' – ', source: 'shared' },
277
// { type: 'month', value: 'Apr', source: 'endRange' },
278
// { type: 'literal', value: ' ', source: 'endRange' },
279
// { type: 'day', value: '10', source: 'endRange' },
280
// { type: 'literal', value: ', ', source: 'shared' },
281
// { type: 'year', value: '2024', source: 'shared' }
282
// ]
283
```
284
285
### Locale-Specific Formatting
286
287
Examples of formatting behavior across different locales and calendar systems.
288
289
**Different Locale Conventions:**
290
291
```typescript
292
import { DateFormatter, CalendarDate } from "@internationalized/date";
293
294
const date = new CalendarDate(2024, 3, 15);
295
const jsDate = date.toDate('UTC');
296
297
// US format (month/day/year)
298
const usFormatter = new DateFormatter('en-US');
299
console.log(usFormatter.format(jsDate)); // "3/15/2024"
300
301
// European format (day/month/year)
302
const ukFormatter = new DateFormatter('en-GB');
303
console.log(ukFormatter.format(jsDate)); // "15/03/2024"
304
305
// German format (day.month.year)
306
const deFormatter = new DateFormatter('de-DE');
307
console.log(deFormatter.format(jsDate)); // "15.3.2024"
308
309
// Japanese format (year/month/day)
310
const jaFormatter = new DateFormatter('ja-JP');
311
console.log(jaFormatter.format(jsDate)); // "2024/3/15"
312
313
// Arabic format (right-to-left)
314
const arFormatter = new DateFormatter('ar-SA');
315
console.log(arFormatter.format(jsDate)); // "١٥/٣/٢٠٢٤"
316
```
317
318
**Calendar System Formatting:**
319
320
```typescript
321
import {
322
DateFormatter,
323
CalendarDate,
324
createCalendar
325
} from "@internationalized/date";
326
327
// Gregorian date
328
const gregorianDate = new CalendarDate(2024, 3, 15);
329
330
// Buddhist date (same absolute date)
331
const buddhistDate = new CalendarDate(createCalendar('buddhist'), 2567, 3, 15);
332
333
// Japanese date with era
334
const japaneseDate = new CalendarDate(createCalendar('japanese'), 'reiwa', 6, 3, 15);
335
336
// Convert to JavaScript Date objects
337
const jsGregorianDate = gregorianDate.toDate('UTC');
338
const jsBuddhistDate = buddhistDate.toDate('UTC');
339
const jsJapaneseDate = japaneseDate.toDate('UTC');
340
341
// Format in appropriate locales
342
const gregorianFormatter = new DateFormatter('en-US');
343
const buddhistFormatter = new DateFormatter('th-TH', { calendar: 'buddhist' });
344
const japaneseFormatter = new DateFormatter('ja-JP', { calendar: 'japanese' });
345
346
console.log(gregorianFormatter.format(jsGregorianDate)); // "3/15/2024"
347
console.log(buddhistFormatter.format(jsBuddhistDate)); // "15/3/2567"
348
console.log(japaneseFormatter.format(jsJapaneseDate)); // "R6/3/15" (Reiwa 6)
349
```
350
351
### Advanced Formatting Options
352
353
Comprehensive formatting options for specialized use cases.
354
355
```typescript
356
import { DateFormatter, CalendarDateTime } from "@internationalized/date";
357
358
const dateTime = new CalendarDateTime(2024, 3, 15, 14, 30, 45);
359
const jsDateTime = dateTime.toDate('UTC');
360
361
// Number formatting options
362
const leadingZeros = new DateFormatter('en-US', {
363
year: 'numeric',
364
month: '2-digit',
365
day: '2-digit',
366
hour: '2-digit',
367
minute: '2-digit',
368
second: '2-digit'
369
});
370
console.log(leadingZeros.format(jsDateTime)); // "03/15/2024, 02:30:45 PM"
371
372
// Text representation options
373
const textFormat = new DateFormatter('en-US', {
374
year: 'numeric',
375
month: 'long',
376
day: 'numeric',
377
weekday: 'long',
378
hour: 'numeric',
379
minute: '2-digit',
380
timeZoneName: 'short'
381
});
382
console.log(textFormat.format(jsDateTime)); // "Friday, March 15, 2024 at 2:30 PM UTC"
383
384
// Hour cycle options
385
const hour24 = new DateFormatter('en-US', {
386
hour: 'numeric',
387
minute: '2-digit',
388
hour12: false
389
});
390
console.log(hour24.format(jsDateTime)); // "14:30"
391
392
const hour12 = new DateFormatter('en-US', {
393
hour: 'numeric',
394
minute: '2-digit',
395
hour12: true
396
});
397
console.log(hour12.format(jsDateTime)); // "2:30 PM"
398
```
399
400
## Usage with Library Date Objects
401
402
To use the DateFormatter with @internationalized/date objects, you must first convert them to JavaScript Date objects using the `toDate()` method:
403
404
```typescript
405
import { DateFormatter, CalendarDate, ZonedDateTime } from "@internationalized/date";
406
407
const calendarDate = new CalendarDate(2024, 3, 15);
408
const zonedDateTime = new ZonedDateTime(2024, 3, 15, 'America/New_York', -5 * 60 * 60 * 1000, 14, 30);
409
410
// Convert to JavaScript Date objects
411
const jsDate = calendarDate.toDate('UTC');
412
const jsZonedDate = zonedDateTime.toDate(); // Already timezone-aware
413
414
// Format with DateFormatter
415
const formatter = new DateFormatter('en-US');
416
console.log(formatter.format(jsDate));
417
console.log(formatter.format(jsZonedDate));
418
```