1 | import dates from './dates';
|
2 |
|
3 | let supportStyles = false;
|
4 | new Intl.DateTimeFormat(undefined, {
|
5 |
|
6 | get dateStyle() {
|
7 | supportStyles = true;
|
8 | }
|
9 |
|
10 | });
|
11 | const dateShort = {
|
12 | day: 'numeric',
|
13 | month: 'numeric',
|
14 | year: 'numeric'
|
15 | };
|
16 | const timeShort = {
|
17 | hour: 'numeric',
|
18 | minute: 'numeric'
|
19 | };
|
20 |
|
21 | const getFormatter = (culture, options) => Intl.DateTimeFormat(culture, options).format;
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | class IntlDateLocalizer {
|
29 | constructor({
|
30 | culture = undefined,
|
31 | firstOfWeek = 0
|
32 | } = {}) {
|
33 | this.culture = culture;
|
34 |
|
35 | this.firstOfWeek = () => firstOfWeek;
|
36 |
|
37 | function normalizeFormat(date, format) {
|
38 | return typeof format === 'function' ? format(date, culture) : date.toLocaleString(culture, format);
|
39 | }
|
40 |
|
41 | const formats = {
|
42 | date: getFormatter(culture,
|
43 | supportStyles ? {
|
44 | dateStyle: 'short'
|
45 | } : dateShort),
|
46 | time: getFormatter(culture,
|
47 | supportStyles ? {
|
48 | timeStyle: 'short'
|
49 | } : timeShort),
|
50 | datetime: getFormatter(culture,
|
51 | supportStyles ? {
|
52 | dateStyle: 'short',
|
53 | timeStyle: 'short'
|
54 | } : Object.assign({}, dateShort, timeShort)),
|
55 | header: getFormatter(culture, {
|
56 | month: 'short',
|
57 | year: 'numeric'
|
58 | }),
|
59 | weekday: getFormatter(culture, {
|
60 | weekday: 'narrow'
|
61 | }),
|
62 | dayOfMonth: getFormatter(culture, {
|
63 | day: '2-digit'
|
64 | }),
|
65 | month: getFormatter(culture, {
|
66 | month: 'short'
|
67 | }),
|
68 | year: getFormatter(culture, {
|
69 | year: 'numeric'
|
70 | }),
|
71 | decade: date => `${this.year(date)} - ${this.year(dates.endOf(date, 'decade'))}`,
|
72 | century: date => `${this.year(date)} - ${this.year(dates.endOf(date, 'century'))}`
|
73 | };
|
74 | Object.keys(formats).forEach(key => {
|
75 | this[key] = (date, format) => format ? normalizeFormat(date, format) : formats[key](date);
|
76 | });
|
77 | }
|
78 |
|
79 | toFormattedParts(date, format = {
|
80 | dateStyle: 'short',
|
81 | timeStyle: 'short'
|
82 | }) {
|
83 | return Intl.DateTimeFormat(this.culture, format).formatToParts(date).filter(p => p.type !== 'timeZoneName');
|
84 | }
|
85 |
|
86 | parse(value) {
|
87 | const date = new Date(value);
|
88 | return isNaN(+date) ? null : date;
|
89 | }
|
90 |
|
91 | }
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | class IntlNumberLocalizer {
|
97 | constructor({
|
98 | culture = undefined
|
99 | } = {}) {
|
100 | var _$toLocaleString$m;
|
101 |
|
102 | this.culture = culture;
|
103 | const decimal = 'formatToParts' in Intl.NumberFormat(culture) ? Intl.NumberFormat(culture).formatToParts(1.1)[1].value : ((_$toLocaleString$m = 1.1.toLocaleString(culture).match(/[^\d]/)) == null ? void 0 : _$toLocaleString$m[0]) || '.';
|
104 | const formatter = Intl.NumberFormat(culture).format;
|
105 |
|
106 | this.decimalCharacter = () => decimal;
|
107 |
|
108 | this.format = (num, format) => {
|
109 | if (format) {
|
110 | return typeof format === 'function' ? format(num, culture) : num.toLocaleString(culture, format);
|
111 | }
|
112 |
|
113 | return formatter(num);
|
114 | };
|
115 | }
|
116 |
|
117 | parse(value) {
|
118 | return parseFloat(value.replace(this.decimalCharacter(), '.'));
|
119 | }
|
120 |
|
121 | }
|
122 |
|
123 | export { IntlDateLocalizer as DateLocalizer, IntlNumberLocalizer as NumberLocalizer }; |
\ | No newline at end of file |