Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 104 additions & 58 deletions lib/date.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/// <reference types="@nextcloud/typings" />

import { getCanonicalLocale } from './locale'

/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-3.0-or-later
Expand All @@ -13,12 +15,30 @@ declare let window: Nextcloud.v27.WindowWithGlobals
* @return {number}
*/
export function getFirstDay(): number {
if (typeof window.firstDay === 'undefined') {
console.warn('No firstDay found')
return 1
// Server rendered
if (typeof window.firstDay !== 'undefined') {
return window.firstDay
}

// Try to fallback to Intl
// getWeekInfo is a Stage 3 proposal and not available in Firefox
// Node.js and Samsung Internet only has accessor property weekInfo instead
type WeekInfoDay = 1 | 2 | 3 | 4 | 5 | 6 | 7
type WeekInfo = {
firstDay: WeekInfoDay,
weekend: WeekInfoDay,
minimalDays: WeekInfoDay,
}
const intl = new Intl.Locale(getCanonicalLocale())
// @ts-expect-error These properties are not part of the standard
const weekInfo: WeekInfo = intl.getWeekInfo?.() ?? intl.weekInfo
if (weekInfo) {
// Convert 1..7 to 0..6 format
return weekInfo.firstDay % 7
}

return window.firstDay
// Fallback to Monday
return 1
}

/**
Expand All @@ -27,20 +47,22 @@ export function getFirstDay(): number {
* @return {string[]}
*/
export function getDayNames(): string[] {
if (typeof window.dayNames === 'undefined') {
console.warn('No dayNames found')
return [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
]
// Server rendered
if (typeof window.dayNames !== 'undefined') {
return window.dayNames
}

return window.dayNames
// Fallback to Intl
const locale = getCanonicalLocale()
return [
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),
]
}

/**
Expand All @@ -49,12 +71,22 @@ export function getDayNames(): string[] {
* @return {string[]}
*/
export function getDayNamesShort(): string[] {
if (typeof window.dayNamesShort === 'undefined') {
console.warn('No dayNamesShort found')
return ['Sun.', 'Mon.', 'Tue.', 'Wed.', 'Thu.', 'Fri.', 'Sat.']
if (typeof window.dayNamesShort !== 'undefined') {
return window.dayNamesShort
}

return window.dayNamesShort
// Fallback to Intl
// Note: narrow is shorter than server's "min", but it's the closest we can get
const locale = getCanonicalLocale()
return [
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),
]
}

/**
Expand All @@ -63,12 +95,22 @@ export function getDayNamesShort(): string[] {
* @return {string[]}
*/
export function getDayNamesMin(): string[] {
if (typeof window.dayNamesMin === 'undefined') {
console.warn('No dayNamesMin found')
return ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
// Server rendered
if (typeof window.dayNamesMin !== 'undefined') {
return window.dayNamesMin
}

return window.dayNamesMin
// Fallback to Intl
const locale = getCanonicalLocale()
return [
new Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
new Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),
]
}

/**
Expand All @@ -77,25 +119,27 @@ export function getDayNamesMin(): string[] {
* @return {string[]}
*/
export function getMonthNames(): string[] {
if (typeof window.monthNames === 'undefined') {
console.warn('No monthNames found')
return [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
]
// Server rendered
if (typeof window.monthNames !== 'undefined') {
return window.monthNames
}

return window.monthNames
// Fallback to Intl
const locale = getCanonicalLocale()
return [
new Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
new Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),
]
}

/**
Expand All @@ -104,23 +148,25 @@ export function getMonthNames(): string[] {
* @return {string[]}
*/
export function getMonthNamesShort(): string[] {
if (typeof window.monthNamesShort === 'undefined') {
console.warn('No monthNamesShort found')
return [
'Jan.',
'Feb.',
'Mar.',
'Apr.',
'May.',
'Jun.',
'Jul.',
'Aug.',
'Sep.',
'Oct.',
'Nov.',
'Dec.',
]
// Server rendered
if (typeof window.monthNamesShort !== 'undefined') {
return window.monthNamesShort
}

return window.monthNamesShort
// Fallback to Intl
const locale = getCanonicalLocale()
return [
new Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
new Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),
]
}
Loading
Loading