UNPKG

@nextcloud/l10n

Version:

Nextcloud localization and translation helpers for apps and libraries

1 lines 14.5 kB
{"version":3,"file":"index.mjs","sources":["../lib/date.ts","../lib/time.ts"],"sourcesContent":["/// <reference types=\"@nextcloud/typings\" />\n/*!\n * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { getCanonicalLocale } from './locale.ts'\n\ndeclare let globalThis: Nextcloud.v29.WindowWithGlobals\n\nexport type WeekDay = 0 | 1 | 2 | 3 | 4 | 5 | 6\n\n/**\n * Get the first day of the week\n *\n * @return The first day where 0 is Sunday, 1 is Monday etc.\n */\nexport function getFirstDay(): WeekDay {\n\t// Server rendered\n\tif (typeof globalThis.firstDay !== 'undefined') {\n\t\treturn globalThis.firstDay as WeekDay\n\t}\n\n\t// Try to fallback to Intl\n\t// getWeekInfo is a Stage 3 proposal and not available in Firefox\n\t// Node.js and Samsung Internet only has accessor property weekInfo instead\n\ttype WeekInfoDay = 1 | 2 | 3 | 4 | 5 | 6 | 7\n\ttype WeekInfo = {\n\t\tfirstDay: WeekInfoDay\n\t\tweekend: WeekInfoDay\n\t\tminimalDays: WeekInfoDay\n\t}\n\tconst intl = new Intl.Locale(getCanonicalLocale())\n\t// @ts-expect-error These properties are not part of the standard\n\tconst weekInfo: WeekInfo = intl.getWeekInfo?.() ?? intl.weekInfo\n\tif (weekInfo) {\n\t\t// Convert 1..7 to 0..6 format\n\t\treturn weekInfo.firstDay % 7 as WeekDay\n\t}\n\n\t// Fallback to Monday\n\treturn 1\n}\n\n/**\n * Get a list of day names (full names)\n */\nexport function getDayNames(): string[] {\n\t// Server rendered\n\tif (typeof globalThis.dayNames !== 'undefined') {\n\t\treturn globalThis.dayNames\n\t}\n\n\t// Fallback to Intl\n\tconst locale = getCanonicalLocale()\n\treturn [\n\t\tnew Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t\tnew Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'long' }),\n\t]\n}\n\n/**\n * Get a list of day names (short names)\n */\nexport function getDayNamesShort(): string[] {\n\tif (typeof globalThis.dayNamesShort !== 'undefined') {\n\t\treturn globalThis.dayNamesShort\n\t}\n\n\t// Fallback to Intl\n\t// Note: narrow is shorter than server's \"min\", but it's the closest we can get\n\tconst locale = getCanonicalLocale()\n\treturn [\n\t\tnew Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t\tnew Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'short' }),\n\t]\n}\n\n/**\n * Get a list of day names (minified names)\n */\nexport function getDayNamesMin(): string[] {\n\t// Server rendered\n\tif (typeof globalThis.dayNamesMin !== 'undefined') {\n\t\treturn globalThis.dayNamesMin\n\t}\n\n\t// Fallback to Intl\n\tconst locale = getCanonicalLocale()\n\treturn [\n\t\tnew Date('1970-01-04T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-05T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-06T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-07T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-08T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-09T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t\tnew Date('1970-01-10T00:00:00.000Z').toLocaleDateString(locale, { weekday: 'narrow' }),\n\t]\n}\n\n/**\n * Get a list of month names (full names)\n */\nexport function getMonthNames(): string[] {\n\t// Server rendered\n\tif (typeof globalThis.monthNames !== 'undefined') {\n\t\treturn globalThis.monthNames\n\t}\n\n\t// Fallback to Intl\n\tconst locale = getCanonicalLocale()\n\treturn [\n\t\tnew Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t\tnew Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'long' }),\n\t]\n}\n\n/**\n * Get a list of month names (short names)\n */\nexport function getMonthNamesShort(): string[] {\n\t// Server rendered\n\tif (typeof globalThis.monthNamesShort !== 'undefined') {\n\t\treturn globalThis.monthNamesShort\n\t}\n\n\t// Fallback to Intl\n\tconst locale = getCanonicalLocale()\n\treturn [\n\t\tnew Date('1970-01-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-02-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-03-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-04-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-05-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-06-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-07-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-08-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-09-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-10-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-11-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t\tnew Date('1970-12-01T00:00:00.000Z').toLocaleDateString(locale, { month: 'short' }),\n\t]\n}\n","/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: GPL-3.0-or-later\n */\n\nimport { getLanguage } from './locale.ts'\n\nexport interface FormatDateOptions {\n\t/**\n\t * If set then instead of showing seconds since the timestamp show the passed message.\n\t *\n\t * @default false\n\t */\n\tignoreSeconds?: string | false\n\n\t/**\n\t * The relative time formatting option to use\n\t *\n\t * @default 'long\n\t */\n\trelativeTime?: 'long' | 'short' | 'narrow'\n\n\t/**\n\t * Language to use\n\t *\n\t * @default 'current language'\n\t */\n\tlanguage?: string\n}\n\n/**\n * Format a given time as \"relative time\" also called \"humanizing\".\n *\n * @param timestamp Timestamp or Date object\n * @param opts Options for the formatting\n */\nexport function formatRelativeTime(\n\ttimestamp: Date | number = Date.now(),\n\topts: FormatDateOptions = {},\n): string {\n\tconst options: Required<FormatDateOptions> = {\n\t\tignoreSeconds: false,\n\t\tlanguage: getLanguage(),\n\t\trelativeTime: 'long' as const,\n\t\t...opts,\n\t}\n\n\t/** ECMA Date object of the timestamp */\n\tconst date = new Date(timestamp)\n\n\tconst formatter = new Intl.RelativeTimeFormat([options.language, getLanguage()], { numeric: 'auto', style: options.relativeTime })\n\tconst diff = date.getTime() - Date.now()\n\tconst seconds = diff / 1000\n\n\tif (Math.abs(seconds) < 59.5) {\n\t\treturn options.ignoreSeconds\n\t\t\t|| formatter.format(Math.round(seconds), 'second')\n\t}\n\n\tconst minutes = seconds / 60\n\tif (Math.abs(minutes) <= 59) {\n\t\treturn formatter.format(Math.round(minutes), 'minute')\n\t}\n\tconst hours = minutes / 60\n\tif (Math.abs(hours) < 23.5) {\n\t\treturn formatter.format(Math.round(hours), 'hour')\n\t}\n\tconst days = hours / 24\n\tif (Math.abs(days) < 6.5) {\n\t\treturn formatter.format(Math.round(days), 'day')\n\t}\n\tif (Math.abs(days) < 27.5) {\n\t\tconst weeks = days / 7\n\t\treturn formatter.format(Math.round(weeks), 'week')\n\t}\n\n\t// For everything above we show year + month like \"August 2025\" or month + day if same year like \"May 12\"\n\t// This is based on a Nextcloud design decision: https://github.com/nextcloud/server/issues/29807#issuecomment-2431895872\n\tconst months = days / 30\n\tconst format: Intl.DateTimeFormatOptions = Math.abs(months) < 11\n\t\t? { month: options.relativeTime, day: 'numeric' }\n\t\t: { year: options.relativeTime === 'narrow' ? '2-digit' : 'numeric', month: options.relativeTime }\n\n\tconst dateTimeFormatter = new Intl.DateTimeFormat([options.language, getLanguage()], format)\n\treturn dateTimeFormatter.format(date)\n}\n"],"names":[],"mappings":"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"}