Skip to content

Commit 6487990

Browse files
feat: replace dateFormatString with a more generic splitDateFormat method
1 parent 8bb6861 commit 6487990

File tree

5 files changed

+248
-48
lines changed

5 files changed

+248
-48
lines changed

src/cldr.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export interface DateFormatNameOptions {
2020
/**
2121
* Specifies whether the standalone names should be returned.
2222
*/
23-
standAlone?: string;
23+
standAlone?: boolean;
2424
}
2525

2626
/**

src/dates.d.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DateFormatNameOptions } from './cldr';
2+
13
/**
24
* Settings for the formatDate and parseDate functions.
35
*/
@@ -7,6 +9,11 @@ export interface DateFormatOptions {
79
*/
810
skeleton?: string;
911

12+
/**
13+
* Defines exact pattern to be used to format the date.
14+
*/
15+
pattern?: string;
16+
1017
/**
1118
* Specifies which of the locale `dateFormats` should be used to format the value.
1219
*/
@@ -93,12 +100,28 @@ export function formatDate(value: Date, format: string|DateFormatOptions, locale
93100
*/
94101
export function parseDate(value: string, format?: string | DateFormatOptions | string[] | DateFormatOptions[], locale?: string): Date;
95102

103+
export interface DateFormatPart {
104+
/**
105+
* Specifies the type of the format part.
106+
*/
107+
type?: 'era' | 'year' | 'quarter' | 'month' | 'day' | 'weekday' | 'hour' | 'minute' | 'second' | 'dayperiod' | 'zone' | 'literal';
108+
109+
/**
110+
* Specifies the pattern of the format part.
111+
*/
112+
pattern?: string;
113+
114+
/**
115+
* Specifies the format names options.
116+
*/
117+
names?: DateFormatNameOptions;
118+
}
119+
96120
/**
97-
* Returns the full format based on the Date object and the specified format. If no format is provided, the default short date format is used.
121+
* Splits the date format into objects containing information about each part of the pattern.
98122
*
99-
* @param value The date to format.
100123
* @param format The format string or options.
101124
* @param locale The optional locale id. If not specified, the `"en"` locale id is used.
102-
* @returns The full date format.
125+
* @returns The date format parts.
103126
*/
104-
export function dateFormatString(value: Date, format: string|DateFormatOptions, locale?: string): string;
127+
export function splitDateFormat(format: string|DateFormatOptions, locale?: string): DateFormatPart[];

src/dates/constants.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ const WEEKDAY = 'weekday';
55
const QUARTER = 'quarter';
66

77
const DATE_FIELD_MAP = {
8+
'G': 'era',
89
'y': 'year',
10+
'q': QUARTER,
11+
'Q': QUARTER,
912
'M': MONTH,
1013
'L': MONTH,
1114
'd': 'day',
12-
'E': 'weekday',
15+
'E': WEEKDAY,
16+
'c': WEEKDAY,
17+
'e': WEEKDAY,
1318
'h': HOUR,
1419
'H': HOUR,
1520
'm': 'minute',
1621
's': 'second',
17-
'a': 'dayPeriod',
22+
'a': 'dayperiod',
1823
'x': ZONE,
1924
'X': ZONE,
2025
'z': ZONE,
21-
'Z': ZONE,
22-
'G': 'era',
23-
'c': WEEKDAY,
24-
'e': WEEKDAY,
25-
'q': QUARTER,
26-
'Q': QUARTER
26+
'Z': ZONE
2727
};
2828

2929
const dateFormatRegExp = /d{1,2}|E{1,6}|e{1,6}|c{3,6}|c{1}|M{1,5}|L{1,5}|y{1,4}|H{1,2}|h{1,2}|m{1,2}|a{1,5}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|x{1,5}|X{1,5}|G{1,5}|q{1,5}|Q{1,5}|"[^"]*"|'[^']*'/g;

src/dates/split-date-format.js

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const NAME_TYPES = {
1919
minLength: 0
2020
},
2121

22-
dayPeriod: {
22+
dayperiod: {
2323
nameType: 'dayPeriods',
2424
minLength: 0
2525
},
@@ -28,8 +28,20 @@ const NAME_TYPES = {
2828
nameType: 'eras',
2929
minLength: 0
3030
}
31-
3231
};
32+
const LITERAL = 'literal';
33+
34+
function addLiteral(parts, value) {
35+
const lastPart = parts[parts.length - 1];
36+
if (lastPart && lastPart.type === LITERAL) {
37+
lastPart.pattern += value;
38+
} else {
39+
parts.push({
40+
type: LITERAL,
41+
pattern: value
42+
});
43+
}
44+
}
3345

3446
export default function splitDateFormat(format, locale = 'en') {
3547
const info = localeInfo(locale);
@@ -42,33 +54,26 @@ export default function splitDateFormat(format, locale = 'en') {
4254
let value = match[0];
4355

4456
if (lastIndex < match.index) {
45-
parts.push({
46-
type: 'literal',
47-
pattern: pattern.substring(lastIndex, match.index)
48-
});
57+
addLiteral(parts, pattern.substring(lastIndex, match.index));
4958
}
5059

5160
if (value.startsWith('"') || value.startsWith("'")) {
52-
parts.push({
53-
type: 'literal' ,
54-
pattern: value
55-
});
61+
addLiteral(parts, value);
5662
} else {
5763
const type = DATE_FIELD_MAP[value[0]];
58-
let names;
64+
const part = {
65+
type: type,
66+
pattern: value
67+
};
5968

6069
if (NAME_TYPES[type] && value.length >= NAME_TYPES[type].minLength) {
61-
names = {
70+
part.names = {
6271
type: NAME_TYPES[type].nameType,
6372
nameType: dateNameType(value.length)
6473
};
6574
}
6675

67-
parts.push({
68-
type: type,
69-
names: names,
70-
pattern: value
71-
});
76+
parts.push(part);
7277
}
7378

7479
lastIndex = dateFormatRegExp.lastIndex;

0 commit comments

Comments
 (0)