-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
index.ts
88 lines (77 loc) · 2.55 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
export interface DateFormat {
day?: 'numeric' | '2-digit'
month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow'
year?: 'numeric' | '2-digit'
}
export default function formatRange<DateType extends Date>(
from: DateType,
to: DateType,
format: DateFormat
): string | undefined {
const defaultFormat: DateFormat = {
day: 'numeric',
month: 'numeric',
year: 'numeric',
}
const mergedFormats: DateFormat = { ...defaultFormat, ...format }
const fromFormattedParts: Intl.DateTimeFormatPart[] = new Intl.DateTimeFormat(
undefined,
mergedFormats
)
.formatToParts(from)
.filter((part) => part.type !== 'literal')
const toFormattedParts: Intl.DateTimeFormatPart[] = new Intl.DateTimeFormat(
undefined,
mergedFormats
)
.formatToParts(to)
.filter((part) => part.type !== 'literal')
if (fromFormattedParts.length > 3 || toFormattedParts.length > 3) {
console.error('Unexpected length of formatted parts array.')
return undefined
}
const datePartsType: string[] = fromFormattedParts.map((part) => part.type)
if (fromFormattedParts === toFormattedParts) {
return fromFormattedParts.join(' ')
} else if (
from.getMonth() === to.getMonth() &&
from.getFullYear() === to.getFullYear()
) {
let format: string = `${getDatePartValueByType(
'day',
fromFormattedParts
)}-${getDatePartValueByType('day', toFormattedParts)}`
datePartsType
.filter((type) => type !== 'day')
.forEach((type) => {
format += ` ${getDatePartValueByType(type, fromFormattedParts)}`
})
return format
} else if (from.getFullYear() === to.getFullYear()) {
const fromFormat: string[] = []
const toFormat: string[] = []
datePartsType
.filter((type) => type !== 'year')
.forEach((type) => {
fromFormat.push(getDatePartValueByType(type, fromFormattedParts))
toFormat.push(getDatePartValueByType(type, toFormattedParts))
})
return `${fromFormat.join(' ')}-${toFormat.join(
' '
)} ${getDatePartValueByType('year', fromFormattedParts)}`
} else {
const fromFormat: string[] = []
const toFormat: string[] = []
datePartsType.forEach((type) => {
fromFormat.push(getDatePartValueByType(type, fromFormattedParts))
toFormat.push(getDatePartValueByType(type, toFormattedParts))
})
return `${fromFormat.join(' ')}-${toFormat.join(' ')}`
}
}
function getDatePartValueByType(
type: string,
dateParts: Intl.DateTimeFormatPart[]
): string {
return dateParts.filter((part) => part.type === type)[0].value
}