diff --git a/apps/client/src/services/utils.ts b/apps/client/src/services/utils.ts index ab6e45847..f5c1f465f 100644 --- a/apps/client/src/services/utils.ts +++ b/apps/client/src/services/utils.ts @@ -124,8 +124,23 @@ function formatDateISO(date: Date) { return `${date.getFullYear()}-${padNum(date.getMonth() + 1)}-${padNum(date.getDate())}`; } -function formatDateTime(date: Date) { - return `${formatDate(date)} ${formatTime(date)}`; + +export function formatDateTime(date: Date, userSuppliedFormat?: string): string { + const DEFAULT_FORMAT = 'YYYY-MM-DD HH:mm'; + const formatToUse = (typeof userSuppliedFormat === 'string' && userSuppliedFormat.trim() !== "") + ? userSuppliedFormat.trim() + : DEFAULT_FORMAT; + + if (!date) { + date = new Date(); + } + + try { + return dayjs(date).format(formatToUse); + } catch (e: any) { + console.warn(`TriliumNext: Day.js encountered an error with format string "${formatToUse}". Falling back to default. Error: ${e.message}`); + return dayjs(date).format(DEFAULT_FORMAT); + } } function localNowDateTime() { diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 4d39265d1..2f0c0e0a8 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -1962,5 +1962,16 @@ "title": "Appearance", "word_wrapping": "Word wrapping", "color-scheme": "Color scheme" + }, + "custom_date_time_format": { + "title": "Custom Date/Time Format (Alt+T)", + "desc1": "Define a custom format for the date and time inserted using the Alt+T shortcut.", + "desc2": "Uses Day.js format tokens. Refer to the Day.js documentation for valid tokens.", + "important_label": "Important:", + "desc3": "If you provide a format string that Day.js does not recognize (e.g., mostly plain text without valid Day.js tokens), the text you typed might be inserted literally. If the format string is left empty, or if Day.js encounters a critical internal error with your format, a default format (e.g., YYYY-MM-DD HH:mm) will be used.", + "format_string_label": "Format String:", + "placeholder": "e.g., DD/MM/YYYY HH:mm:ss or dddd, MMMM D", + "examples_label": "Examples of valid Day.js formats:", + "example_default": "Default-like" } } diff --git a/apps/client/src/widgets/type_widgets/content_widget.ts b/apps/client/src/widgets/type_widgets/content_widget.ts index 00c30f5f7..aa3eadcb0 100644 --- a/apps/client/src/widgets/type_widgets/content_widget.ts +++ b/apps/client/src/widgets/type_widgets/content_widget.ts @@ -45,6 +45,7 @@ import LanguageOptions from "./options/i18n/language.js"; import type BasicWidget from "../basic_widget.js"; import CodeTheme from "./options/code_notes/code_theme.js"; import RelatedSettings from "./options/related_settings.js"; +import DateTimeFormatOptions from "./options/text_notes/date_time_format.js"; const TPL = /*html*/`