Skip to content

Commit 0624cb7

Browse files
authored
Merge pull request #831 from nextcloud-libraries/feat/date--fallback-to-Intl
feat(date): fallback to Intl
2 parents 08cdafe + d1a192a commit 0624cb7

File tree

2 files changed

+242
-120
lines changed

2 files changed

+242
-120
lines changed

lib/date.ts

Lines changed: 104 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/// <reference types="@nextcloud/typings" />
22

3+
import { getCanonicalLocale } from './locale'
4+
35
/**
46
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
57
* SPDX-License-Identifier: GPL-3.0-or-later
@@ -13,12 +15,30 @@ declare let window: Nextcloud.v27.WindowWithGlobals
1315
* @return {number}
1416
*/
1517
export function getFirstDay(): number {
16-
if (typeof window.firstDay === 'undefined') {
17-
console.warn('No firstDay found')
18-
return 1
18+
// Server rendered
19+
if (typeof window.firstDay !== 'undefined') {
20+
return window.firstDay
21+
}
22+
23+
// Try to fallback to Intl
24+
// getWeekInfo is a Stage 3 proposal and not available in Firefox
25+
// Node.js and Samsung Internet only has accessor property weekInfo instead
26+
type WeekInfoDay = 1 | 2 | 3 | 4 | 5 | 6 | 7
27+
type WeekInfo = {
28+
firstDay: WeekInfoDay,
29+
weekend: WeekInfoDay,
30+
minimalDays: WeekInfoDay,
31+
}
32+
const intl = new Intl.Locale(getCanonicalLocale())
33+
// @ts-expect-error These properties are not part of the standard
34+
const weekInfo: WeekInfo = intl.getWeekInfo?.() ?? intl.weekInfo
35+
if (weekInfo) {
36+
// Convert 1..7 to 0..6 format
37+
return weekInfo.firstDay % 7
1938
}
2039

21-
return window.firstDay
40+
// Fallback to Monday
41+
return 1
2242
}
2343

2444
/**
@@ -27,20 +47,22 @@ export function getFirstDay(): number {
2747
* @return {string[]}
2848
*/
2949
export function getDayNames(): string[] {
30-
if (typeof window.dayNames === 'undefined') {
31-
console.warn('No dayNames found')
32-
return [
33-
'Sunday',
34-
'Monday',
35-
'Tuesday',
36-
'Wednesday',
37-
'Thursday',
38-
'Friday',
39-
'Saturday',
40-
]
50+
// Server rendered
51+
if (typeof window.dayNames !== 'undefined') {
52+
return window.dayNames
4153
}
4254

43-
return window.dayNames
55+
// Fallback to Intl
56+
const locale = getCanonicalLocale()
57+
return [
58+
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
59+
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
60+
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
61+
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
62+
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
63+
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
64+
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
65+
]
4466
}
4567

4668
/**
@@ -49,12 +71,22 @@ export function getDayNames(): string[] {
4971
* @return {string[]}
5072
*/
5173
export function getDayNamesShort(): string[] {
52-
if (typeof window.dayNamesShort === 'undefined') {
53-
console.warn('No dayNamesShort found')
54-
return ['Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.']
74+
if (typeof window.dayNamesShort !== 'undefined') {
75+
return window.dayNamesShort
5576
}
5677

57-
return window.dayNamesShort
78+
// Fallback to Intl
79+
// Note: narrow is shorter than server's "min", but it's the closest we can get
80+
const locale = getCanonicalLocale()
81+
return [
82+
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
83+
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
84+
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
85+
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
86+
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
87+
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
88+
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
89+
]
5890
}
5991

6092
/**
@@ -63,12 +95,22 @@ export function getDayNamesShort(): string[] {
6395
* @return {string[]}
6496
*/
6597
export function getDayNamesMin(): string[] {
66-
if (typeof window.dayNamesMin === 'undefined') {
67-
console.warn('No dayNamesMin found')
68-
return ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
98+
// Server rendered
99+
if (typeof window.dayNamesMin !== 'undefined') {
100+
return window.dayNamesMin
69101
}
70102

71-
return window.dayNamesMin
103+
// Fallback to Intl
104+
const locale = getCanonicalLocale()
105+
return [
106+
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
107+
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
108+
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
109+
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
110+
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
111+
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
112+
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
113+
]
72114
}
73115

74116
/**
@@ -77,25 +119,27 @@ export function getDayNamesMin(): string[] {
77119
* @return {string[]}
78120
*/
79121
export function getMonthNames(): string[] {
80-
if (typeof window.monthNames === 'undefined') {
81-
console.warn('No monthNames found')
82-
return [
83-
'January',
84-
'February',
85-
'March',
86-
'April',
87-
'May',
88-
'June',
89-
'July',
90-
'August',
91-
'September',
92-
'October',
93-
'November',
94-
'December',
95-
]
122+
// Server rendered
123+
if (typeof window.monthNames !== 'undefined') {
124+
return window.monthNames
96125
}
97126

98-
return window.monthNames
127+
// Fallback to Intl
128+
const locale = getCanonicalLocale()
129+
return [
130+
new Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
131+
new Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
132+
new Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
133+
new Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
134+
new Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
135+
new Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
136+
new Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
137+
new Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
138+
new Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
139+
new Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
140+
new Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
141+
new Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
142+
]
99143
}
100144

101145
/**
@@ -104,23 +148,25 @@ export function getMonthNames(): string[] {
104148
* @return {string[]}
105149
*/
106150
export function getMonthNamesShort(): string[] {
107-
if (typeof window.monthNamesShort === 'undefined') {
108-
console.warn('No monthNamesShort found')
109-
return [
110-
'Jan.',
111-
'Feb.',
112-
'Mar.',
113-
'Apr.',
114-
'May.',
115-
'Jun.',
116-
'Jul.',
117-
'Aug.',
118-
'Sep.',
119-
'Oct.',
120-
'Nov.',
121-
'Dec.',
122-
]
151+
// Server rendered
152+
if (typeof window.monthNamesShort !== 'undefined') {
153+
return window.monthNamesShort
123154
}
124155

125-
return window.monthNamesShort
156+
// Fallback to Intl
157+
const locale = getCanonicalLocale()
158+
return [
159+
new Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
160+
new Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
161+
new Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
162+
new Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
163+
new Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
164+
new Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
165+
new Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
166+
new Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
167+
new Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
168+
new Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
169+
new Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
170+
new Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
171+
]
126172
}

0 commit comments

Comments
 (0)