0
# International Formatting
1
2
Enhanced `Intl.DateTimeFormat` class with native Temporal type support for formatting dates and times. Provides seamless integration between Temporal objects and internationalization features.
3
4
## Capabilities
5
6
### Enhanced DateTimeFormat
7
8
Extended version of `Intl.DateTimeFormat` that supports all Temporal types in addition to legacy Date objects.
9
10
```typescript { .api }
11
/**
12
* Enhanced DateTimeFormat class supporting Temporal types
13
*/
14
class DateTimeFormat extends Intl.DateTimeFormat {
15
/** Creates a new DateTimeFormat instance */
16
constructor(locales?: LocalesArgument, options?: Intl.DateTimeFormatOptions);
17
18
/** Formats a Temporal object or Date as a string */
19
format(date: TemporalFormattable | Date): string;
20
21
/** Formats a Temporal object or Date into an array of parts */
22
formatToParts(date: TemporalFormattable | Date): Intl.DateTimeFormatPart[];
23
24
/** Formats a range between two Temporal objects */
25
formatRange(startDate: TemporalFormattable, endDate: TemporalFormattable): string;
26
27
/** Formats a range between two Temporal objects into an array of parts */
28
formatRangeToParts(startDate: TemporalFormattable, endDate: TemporalFormattable): Intl.DateTimeFormatPart[];
29
30
/** Returns the supported locales */
31
static supportedLocalesOf(locales: LocalesArgument, options?: Intl.SupportedLocalesOptions): string[];
32
}
33
```
34
35
### Supported Temporal Types
36
37
The enhanced DateTimeFormat supports all major Temporal types for formatting.
38
39
```typescript { .api }
40
/**
41
* Union type of all Temporal objects that can be formatted
42
*/
43
type TemporalFormattable =
44
| Instant
45
| ZonedDateTime
46
| PlainDateTime
47
| PlainDate
48
| PlainTime
49
| PlainYearMonth
50
| PlainMonthDay;
51
52
type LocalesArgument = string | string[] | undefined;
53
```
54
55
### Formatting Individual Temporal Types
56
57
Format specific Temporal types with locale-appropriate output.
58
59
**Usage Examples:**
60
61
```typescript
62
import { Temporal, Intl } from "temporal-polyfill";
63
64
// Create formatter instances
65
const dateFormatter = new Intl.DateTimeFormat('en-US', {
66
year: 'numeric',
67
month: 'long',
68
day: 'numeric'
69
});
70
71
const timeFormatter = new Intl.DateTimeFormat('en-US', {
72
hour: 'numeric',
73
minute: '2-digit',
74
second: '2-digit',
75
timeZoneName: 'short'
76
});
77
78
const dateTimeFormatter = new Intl.DateTimeFormat('en-US', {
79
weekday: 'long',
80
year: 'numeric',
81
month: 'long',
82
day: 'numeric',
83
hour: 'numeric',
84
minute: '2-digit',
85
timeZone: 'America/New_York'
86
});
87
88
// Format PlainDate
89
const plainDate = Temporal.PlainDate.from('2024-03-15');
90
console.log(dateFormatter.format(plainDate)); // "March 15, 2024"
91
92
// Format PlainTime
93
const plainTime = Temporal.PlainTime.from('14:30:00');
94
console.log(timeFormatter.format(plainTime)); // "2:30:00 PM GMT"
95
96
// Format PlainDateTime
97
const plainDateTime = Temporal.PlainDateTime.from('2024-03-15T14:30:00');
98
console.log(dateTimeFormatter.format(plainDateTime)); // "Friday, March 15, 2024 at 2:30 PM EST"
99
100
// Format ZonedDateTime
101
const zonedDateTime = Temporal.ZonedDateTime.from('2024-03-15T14:30:00[America/New_York]');
102
console.log(dateTimeFormatter.format(zonedDateTime)); // "Friday, March 15, 2024 at 2:30 PM EDT"
103
104
// Format Instant
105
const instant = Temporal.Now.instant();
106
console.log(dateTimeFormatter.format(instant)); // Current time in New York timezone
107
108
// Format PlainYearMonth
109
const yearMonthFormatter = new Intl.DateTimeFormat('en-US', {
110
year: 'numeric',
111
month: 'long'
112
});
113
const yearMonth = Temporal.PlainYearMonth.from('2024-03');
114
console.log(yearMonthFormatter.format(yearMonth)); // "March 2024"
115
116
// Format PlainMonthDay
117
const monthDayFormatter = new Intl.DateTimeFormat('en-US', {
118
month: 'long',
119
day: 'numeric'
120
});
121
const monthDay = Temporal.PlainMonthDay.from('03-15');
122
console.log(monthDayFormatter.format(monthDay)); // "March 15"
123
```
124
125
### Localized Formatting
126
127
Format Temporal objects in different locales with appropriate cultural conventions.
128
129
**Usage Examples:**
130
131
```typescript
132
import { Temporal, Intl } from "temporal-polyfill";
133
134
const dateTime = Temporal.ZonedDateTime.from('2024-03-15T14:30:00[Europe/Paris]');
135
136
// Different locales
137
const locales = ['en-US', 'fr-FR', 'de-DE', 'ja-JP', 'ar-SA'];
138
139
const formatters = locales.map(locale => ({
140
locale,
141
formatter: new Intl.DateTimeFormat(locale, {
142
weekday: 'long',
143
year: 'numeric',
144
month: 'long',
145
day: 'numeric',
146
hour: 'numeric',
147
minute: '2-digit',
148
timeZoneName: 'short'
149
})
150
}));
151
152
formatters.forEach(({ locale, formatter }) => {
153
console.log(`${locale}: ${formatter.format(dateTime)}`);
154
});
155
156
// Output examples:
157
// en-US: Friday, March 15, 2024 at 2:30 PM CET
158
// fr-FR: vendredi 15 mars 2024 à 14:30 CET
159
// de-DE: Freitag, 15. März 2024 um 14:30 CET
160
// ja-JP: 2024年3月15日金曜日 14:30 CET
161
// ar-SA: الجمعة، ١٥ مارس ٢٠٢٤ في ٢:٣٠ م CET
162
163
// Currency and number formatting in dates
164
const businessFormatter = new Intl.DateTimeFormat('en-US', {
165
month: 'short',
166
day: 'numeric',
167
year: 'numeric',
168
hour: 'numeric',
169
minute: '2-digit',
170
timeZone: 'America/New_York'
171
});
172
173
const businessDate = Temporal.ZonedDateTime.from('2024-03-15T16:30:00[America/New_York]');
174
console.log(`Report generated: ${businessFormatter.format(businessDate)}`);
175
// "Report generated: Mar 15, 2024 at 4:30 PM"
176
```
177
178
### Format to Parts
179
180
Get detailed formatting parts for custom display and analysis.
181
182
**Usage Examples:**
183
184
```typescript
185
import { Temporal, Intl } from "temporal-polyfill";
186
187
const dateTime = Temporal.ZonedDateTime.from('2024-03-15T14:30:00[America/New_York]');
188
189
const formatter = new Intl.DateTimeFormat('en-US', {
190
weekday: 'long',
191
year: 'numeric',
192
month: 'long',
193
day: 'numeric',
194
hour: 'numeric',
195
minute: '2-digit',
196
timeZoneName: 'short'
197
});
198
199
const parts = formatter.formatToParts(dateTime);
200
console.log(parts);
201
202
// Example output:
203
// [
204
// { type: 'weekday', value: 'Friday' },
205
// { type: 'literal', value: ', ' },
206
// { type: 'month', value: 'March' },
207
// { type: 'literal', value: ' ' },
208
// { type: 'day', value: '15' },
209
// { type: 'literal', value: ', ' },
210
// { type: 'year', value: '2024' },
211
// { type: 'literal', value: ' at ' },
212
// { type: 'hour', value: '2' },
213
// { type: 'literal', value: ':' },
214
// { type: 'minute', value: '30' },
215
// { type: 'literal', value: ' ' },
216
// { type: 'dayPeriod', value: 'PM' },
217
// { type: 'literal', value: ' ' },
218
// { type: 'timeZoneName', value: 'EDT' }
219
// ]
220
221
// Use parts for custom formatting
222
function formatWithHighlight(temporal: TemporalFormattable): string {
223
const parts = formatter.formatToParts(temporal);
224
return parts
225
.map(part => {
226
if (part.type === 'weekday' || part.type === 'month') {
227
return `<strong>${part.value}</strong>`;
228
}
229
return part.value;
230
})
231
.join('');
232
}
233
234
console.log(formatWithHighlight(dateTime));
235
// "<strong>Friday</strong>, <strong>March</strong> 15, 2024 at 2:30 PM EDT"
236
```
237
238
### Range Formatting
239
240
Format ranges between two Temporal objects with intelligent range handling.
241
242
**Usage Examples:**
243
244
```typescript
245
import { Temporal, Intl } from "temporal-polyfill";
246
247
const rangeFormatter = new Intl.DateTimeFormat('en-US', {
248
year: 'numeric',
249
month: 'short',
250
day: 'numeric',
251
hour: 'numeric',
252
minute: '2-digit',
253
timeZone: 'America/New_York'
254
});
255
256
// Date range (same day)
257
const startTime = Temporal.ZonedDateTime.from('2024-03-15T14:30:00[America/New_York]');
258
const endTime = Temporal.ZonedDateTime.from('2024-03-15T16:00:00[America/New_York]');
259
260
console.log(rangeFormatter.formatRange(startTime, endTime));
261
// "Mar 15, 2024, 2:30 PM – 4:00 PM"
262
263
// Date range (different days)
264
const startDate = Temporal.PlainDate.from('2024-03-15');
265
const endDate = Temporal.PlainDate.from('2024-03-17');
266
267
const dateRangeFormatter = new Intl.DateTimeFormat('en-US', {
268
year: 'numeric',
269
month: 'short',
270
day: 'numeric'
271
});
272
273
console.log(dateRangeFormatter.formatRange(startDate, endDate));
274
// "Mar 15 – 17, 2024"
275
276
// Month range
277
const startMonth = Temporal.PlainYearMonth.from('2024-01');
278
const endMonth = Temporal.PlainYearMonth.from('2024-03');
279
280
const monthRangeFormatter = new Intl.DateTimeFormat('en-US', {
281
year: 'numeric',
282
month: 'long'
283
});
284
285
console.log(monthRangeFormatter.formatRange(startMonth, endMonth));
286
// "January – March 2024"
287
288
// Range parts for custom formatting
289
const rangeParts = rangeFormatter.formatRangeToParts(startTime, endTime);
290
console.log(rangeParts);
291
292
// Example output:
293
// [
294
// { type: 'month', value: 'Mar', source: 'startRange' },
295
// { type: 'literal', value: ' ', source: 'startRange' },
296
// { type: 'day', value: '15', source: 'startRange' },
297
// { type: 'literal', value: ', ', source: 'startRange' },
298
// { type: 'year', value: '2024', source: 'startRange' },
299
// { type: 'literal', value: ', ', source: 'startRange' },
300
// { type: 'hour', value: '2', source: 'startRange' },
301
// { type: 'literal', value: ':', source: 'startRange' },
302
// { type: 'minute', value: '30', source: 'startRange' },
303
// { type: 'literal', value: ' ', source: 'startRange' },
304
// { type: 'dayPeriod', value: 'PM', source: 'startRange' },
305
// { type: 'literal', value: ' – ', source: 'shared' },
306
// { type: 'hour', value: '4', source: 'endRange' },
307
// { type: 'literal', value: ':', source: 'endRange' },
308
// { type: 'minute', value: '00', source: 'endRange' },
309
// { type: 'literal', value: ' ', source: 'endRange' },
310
// { type: 'dayPeriod', value: 'PM', source: 'endRange' }
311
// ]
312
```
313
314
### Business Applications
315
316
Common patterns for using Intl formatting in business applications.
317
318
**Usage Examples:**
319
320
```typescript
321
import { Temporal, Intl } from "temporal-polyfill";
322
323
// Meeting scheduler with international support
324
class MeetingScheduler {
325
private readonly formatter: Intl.DateTimeFormat;
326
327
constructor(locale: string, timeZone: string) {
328
this.formatter = new Intl.DateTimeFormat(locale, {
329
weekday: 'long',
330
year: 'numeric',
331
month: 'long',
332
day: 'numeric',
333
hour: 'numeric',
334
minute: '2-digit',
335
timeZone
336
});
337
}
338
339
formatMeeting(
340
startTime: Temporal.ZonedDateTime,
341
duration: Temporal.Duration
342
): string {
343
const endTime = startTime.add(duration);
344
return this.formatter.formatRange(startTime, endTime);
345
}
346
347
formatMeetingInvite(
348
startTime: Temporal.ZonedDateTime,
349
duration: Temporal.Duration,
350
attendeeTimeZones: string[]
351
): string[] {
352
return attendeeTimeZones.map(tz => {
353
const localStart = startTime.withTimeZone(tz);
354
const localEnd = localStart.add(duration);
355
const localFormatter = new Intl.DateTimeFormat(undefined, {
356
weekday: 'long',
357
year: 'numeric',
358
month: 'long',
359
day: 'numeric',
360
hour: 'numeric',
361
minute: '2-digit',
362
timeZone: tz,
363
timeZoneName: 'short'
364
});
365
return localFormatter.formatRange(localStart, localEnd);
366
});
367
}
368
}
369
370
// Report generation with localization
371
class ReportGenerator {
372
generateTimeStampedReport(
373
data: any,
374
locale: string = 'en-US',
375
timeZone: string = Temporal.Now.timeZoneId()
376
): object {
377
const now = Temporal.Now.zonedDateTimeISO(timeZone);
378
const formatter = new Intl.DateTimeFormat(locale, {
379
year: 'numeric',
380
month: 'long',
381
day: 'numeric',
382
hour: 'numeric',
383
minute: '2-digit',
384
second: '2-digit',
385
timeZoneName: 'short'
386
});
387
388
return {
389
generatedAt: formatter.format(now),
390
timeZone,
391
locale,
392
data
393
};
394
}
395
396
formatDateRange(
397
startDate: Temporal.PlainDate,
398
endDate: Temporal.PlainDate,
399
locale: string = 'en-US'
400
): string {
401
const formatter = new Intl.DateTimeFormat(locale, {
402
year: 'numeric',
403
month: 'short',
404
day: 'numeric'
405
});
406
return formatter.formatRange(startDate, endDate);
407
}
408
}
409
410
// Event calendar with multiple time zones
411
class EventCalendar {
412
formatEventForTimezone(
413
event: {
414
start: Temporal.ZonedDateTime,
415
end: Temporal.ZonedDateTime,
416
title: string
417
},
418
targetTimeZone: string,
419
locale: string = 'en-US'
420
): string {
421
const localStart = event.start.withTimeZone(targetTimeZone);
422
const localEnd = event.end.withTimeZone(targetTimeZone);
423
424
const formatter = new Intl.DateTimeFormat(locale, {
425
month: 'short',
426
day: 'numeric',
427
hour: 'numeric',
428
minute: '2-digit',
429
timeZone: targetTimeZone,
430
timeZoneName: 'short'
431
});
432
433
const timeRange = formatter.formatRange(localStart, localEnd);
434
return `${event.title}: ${timeRange}`;
435
}
436
}
437
```
438
439
## Types
440
441
```typescript { .api }
442
// Type definitions for international formatting
443
type TemporalFormattable =
444
| Instant
445
| ZonedDateTime
446
| PlainDateTime
447
| PlainDate
448
| PlainTime
449
| PlainYearMonth
450
| PlainMonthDay;
451
452
type LocalesArgument = string | string[] | undefined;
453
454
// Enhanced DateTimeFormat interface
455
interface DateTimeFormat extends Intl.DateTimeFormat {
456
format(date: TemporalFormattable | Date): string;
457
formatToParts(date: TemporalFormattable | Date): Intl.DateTimeFormatPart[];
458
formatRange(startDate: TemporalFormattable, endDate: TemporalFormattable): string;
459
formatRangeToParts(startDate: TemporalFormattable, endDate: TemporalFormattable): Intl.DateTimeFormatPart[];
460
}
461
462
// Standard Intl.DateTimeFormatPart with range source information
463
interface DateTimeFormatPart extends Intl.DateTimeFormatPart {
464
source?: 'startRange' | 'endRange' | 'shared';
465
}
466
467
// Standard Intl.DateTimeFormatOptions (extended for Temporal)
468
interface DateTimeFormatOptions extends Intl.DateTimeFormatOptions {
469
// All standard Intl.DateTimeFormatOptions are supported
470
// when formatting Temporal objects
471
}
472
473
// Extended Intl namespace
474
interface IntlExtended extends Intl {
475
DateTimeFormat: DateTimeFormat;
476
}
477
478
// Common format part types
479
type FormatPartType =
480
| 'era'
481
| 'year'
482
| 'month'
483
| 'day'
484
| 'weekday'
485
| 'hour'
486
| 'minute'
487
| 'second'
488
| 'timeZoneName'
489
| 'dayPeriod'
490
| 'literal'
491
| 'fractionalSecond';
492
```