mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	Merge pull request #741 from TriliumNext/feat/formatted-dates
Format dates and times
This commit is contained in:
		
							
								
								
									
										34
									
								
								src/public/app/utils/formatters.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/public/app/utils/formatters.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | /** | ||||||
|  |  * Formats the given date and time to a string based on the current locale. | ||||||
|  |  * @param {string | Date | number} date  | ||||||
|  |  * @param {"full" | "long" | "medium" | "short" | "none" | undefined} dateStyle  | ||||||
|  |  * @param {"full" | "long" | "medium" | "short" | "none" | undefined} timeStyle  | ||||||
|  |  */ | ||||||
|  | export function formatDateTime(date, dateStyle = "medium", timeStyle = "medium") { | ||||||
|  |     const locale = navigator.language; | ||||||
|  |  | ||||||
|  |     let parsedDate; | ||||||
|  |     if (typeof date === "string") { | ||||||
|  |         // Parse the given string as a date | ||||||
|  |         parsedDate = new Date(date); | ||||||
|  |     } else if (typeof date === "number" || date instanceof Date) { | ||||||
|  |         // The given date is already a Date instance or a number | ||||||
|  |         parsedDate = date; | ||||||
|  |     } else { | ||||||
|  |         // Invalid type | ||||||
|  |         throw new TypeError(`Invalid type for the "date" argument.`); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     if (timeStyle === "none") { | ||||||
|  |         // Format only the date | ||||||
|  |         return parsedDate.toLocaleDateString(locale, {dateStyle}); | ||||||
|  |     } else if (dateStyle === "none") { | ||||||
|  |         // Format only the time | ||||||
|  |         return parsedDate.toLocaleTimeString(locale, {timeStyle}); | ||||||
|  |     } else { | ||||||
|  |         // Format the date and time | ||||||
|  |         const formatter = new Intl.DateTimeFormat(navigator.language, {dateStyle, timeStyle}); | ||||||
|  |         return formatter.format(parsedDate); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -1,8 +1,9 @@ | |||||||
| import server from "../../services/server.js"; | import { formatDateTime } from "../../utils/formatters.js" | ||||||
| import utils from "../../services/utils.js"; |  | ||||||
| import { t } from "../../services/i18n.js"; | import { t } from "../../services/i18n.js"; | ||||||
| import BasicWidget from "../basic_widget.js"; | import BasicWidget from "../basic_widget.js"; | ||||||
| import openService from "../../services/open.js"; | import openService from "../../services/open.js"; | ||||||
|  | import server from "../../services/server.js"; | ||||||
|  | import utils from "../../services/utils.js"; | ||||||
|  |  | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| @@ -68,7 +69,7 @@ export default class AboutDialog extends BasicWidget { | |||||||
|         this.$appVersion.text(appInfo.appVersion); |         this.$appVersion.text(appInfo.appVersion); | ||||||
|         this.$dbVersion.text(appInfo.dbVersion); |         this.$dbVersion.text(appInfo.dbVersion); | ||||||
|         this.$syncVersion.text(appInfo.syncVersion); |         this.$syncVersion.text(appInfo.syncVersion); | ||||||
|         this.$buildDate.text(appInfo.buildDate); |         this.$buildDate.text(formatDateTime(appInfo.buildDate)); | ||||||
|         this.$buildRevision.text(appInfo.buildRevision); |         this.$buildRevision.text(appInfo.buildRevision); | ||||||
|         this.$buildRevision.attr('href', `https://github.com/TriliumNext/Notes/commit/${appInfo.buildRevision}`); |         this.$buildRevision.attr('href', `https://github.com/TriliumNext/Notes/commit/${appInfo.buildRevision}`); | ||||||
|         if (utils.isElectron()) { |         if (utils.isElectron()) { | ||||||
|   | |||||||
| @@ -1,13 +1,14 @@ | |||||||
|  | import { formatDateTime } from "../../utils/formatters.js" | ||||||
| import { t } from "../../services/i18n.js"; | import { t } from "../../services/i18n.js"; | ||||||
| import linkService from '../../services/link.js'; |  | ||||||
| import utils from '../../services/utils.js'; |  | ||||||
| import server from '../../services/server.js'; |  | ||||||
| import froca from "../../services/froca.js"; |  | ||||||
| import appContext from "../../components/app_context.js"; | import appContext from "../../components/app_context.js"; | ||||||
| import hoistedNoteService from "../../services/hoisted_note.js"; |  | ||||||
| import BasicWidget from "../basic_widget.js"; | import BasicWidget from "../basic_widget.js"; | ||||||
| import dialogService from "../../services/dialog.js"; | import dialogService from "../../services/dialog.js"; | ||||||
|  | import froca from "../../services/froca.js"; | ||||||
|  | import hoistedNoteService from "../../services/hoisted_note.js"; | ||||||
|  | import linkService from '../../services/link.js'; | ||||||
|  | import server from '../../services/server.js'; | ||||||
| import toastService from "../../services/toast.js"; | import toastService from "../../services/toast.js"; | ||||||
|  | import utils from '../../services/utils.js'; | ||||||
| import ws from "../../services/ws.js"; | import ws from "../../services/ws.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| @@ -71,10 +72,11 @@ export default class RecentChangesDialog extends BasicWidget { | |||||||
|         for (const [dateDay, dayChanges] of groupedByDate) { |         for (const [dateDay, dayChanges] of groupedByDate) { | ||||||
|             const $changesList = $('<ul>'); |             const $changesList = $('<ul>'); | ||||||
|  |  | ||||||
|             const dayEl = $('<div>').append($('<b>').text(dateDay)).append($changesList); |             const formattedDate = formatDateTime(dateDay, "full", "none"); | ||||||
|  |             const dayEl = $('<div>').append($('<b>').text(formattedDate)).append($changesList); | ||||||
|  |  | ||||||
|             for (const change of dayChanges) { |             for (const change of dayChanges) { | ||||||
|                 const formattedTime = change.date.substr(11, 5); |                 const formattedTime = formatDateTime(change.date, "none", "short"); | ||||||
|  |  | ||||||
|                 let $noteLink; |                 let $noteLink; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
|  | import { formatDateTime } from "../../utils/formatters.js" | ||||||
|  | import { t } from "../../services/i18n.js"; | ||||||
| import NoteContextAwareWidget from "../note_context_aware_widget.js"; | import NoteContextAwareWidget from "../note_context_aware_widget.js"; | ||||||
| import server from "../../services/server.js"; | import server from "../../services/server.js"; | ||||||
| import utils from "../../services/utils.js"; | import utils from "../../services/utils.js"; | ||||||
| import { t } from "../../services/i18n.js"; |  | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="note-info-widget"> | <div class="note-info-widget"> | ||||||
| @@ -121,11 +123,11 @@ export default class NoteInfoWidget extends NoteContextAwareWidget { | |||||||
|  |  | ||||||
|         this.$noteId.text(note.noteId); |         this.$noteId.text(note.noteId); | ||||||
|         this.$dateCreated |         this.$dateCreated | ||||||
|             .text(metadata.dateCreated.substr(0, 16)) |             .text(formatDateTime(metadata.dateCreated)) | ||||||
|             .attr("title", metadata.dateCreated); |             .attr("title", metadata.dateCreated); | ||||||
|  |  | ||||||
|         this.$dateModified |         this.$dateModified | ||||||
|             .text(metadata.dateModified.substr(0, 16)) |             .text(formatDateTime(metadata.dateModified)) | ||||||
|             .attr("title", metadata.dateModified); |             .attr("title", metadata.dateModified); | ||||||
|  |  | ||||||
|         this.$type.text(note.type); |         this.$type.text(note.type); | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
|  | import { formatDateTime } from "../../../utils/formatters.js" | ||||||
| import { t } from "../../../services/i18n.js"; | import { t } from "../../../services/i18n.js"; | ||||||
|  | import OptionsWidget from "./options_widget.js"; | ||||||
| import server from "../../../services/server.js"; | import server from "../../../services/server.js"; | ||||||
| import toastService from "../../../services/toast.js"; | import toastService from "../../../services/toast.js"; | ||||||
| import OptionsWidget from "./options_widget.js"; |  | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="options-section"> | <div class="options-section"> | ||||||
| @@ -115,15 +116,10 @@ export default class BackupOptions extends OptionsWidget { | |||||||
|                 return 0; |                 return 0; | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             const dateTimeFormatter = new Intl.DateTimeFormat(navigator.language, { |  | ||||||
|                 dateStyle: "medium", |  | ||||||
|                 timeStyle: "medium" |  | ||||||
|             }); |  | ||||||
|  |  | ||||||
|             for (const {filePath, mtime} of backupFiles) { |             for (const {filePath, mtime} of backupFiles) { | ||||||
|                 this.$existingBackupList.append($(` |                 this.$existingBackupList.append($(` | ||||||
|                     <tr> |                     <tr> | ||||||
|                         <td>${(mtime) ? dateTimeFormatter.format(new Date(mtime)) : "-"}</td> |                         <td>${(mtime) ? formatDateTime(mtime) : "-"}</td> | ||||||
|                         <td>${filePath}</td> |                         <td>${filePath}</td> | ||||||
|                     </tr> |                     </tr> | ||||||
|                 `)); |                 `)); | ||||||
|   | |||||||
| @@ -1,8 +1,9 @@ | |||||||
|  | import { formatDateTime } from "../../../utils/formatters.js" | ||||||
| import { t } from "../../../services/i18n.js"; | import { t } from "../../../services/i18n.js"; | ||||||
| import server from "../../../services/server.js"; |  | ||||||
| import dialogService from "../../../services/dialog.js"; | import dialogService from "../../../services/dialog.js"; | ||||||
| import toastService from "../../../services/toast.js"; |  | ||||||
| import OptionsWidget from "./options_widget.js"; | import OptionsWidget from "./options_widget.js"; | ||||||
|  | import server from "../../../services/server.js"; | ||||||
|  | import toastService from "../../../services/toast.js"; | ||||||
|  |  | ||||||
| const TPL = ` | const TPL = ` | ||||||
| <div class="options-section"> | <div class="options-section"> | ||||||
| @@ -95,7 +96,7 @@ export default class EtapiOptions extends OptionsWidget { | |||||||
|             $tokensTableBody.append( |             $tokensTableBody.append( | ||||||
|                 $("<tr>") |                 $("<tr>") | ||||||
|                     .append($("<td>").text(token.name)) |                     .append($("<td>").text(token.name)) | ||||||
|                     .append($("<td>").text(token.utcDateCreated)) |                     .append($("<td>").text(formatDateTime(token.utcDateCreated))) | ||||||
|                     .append($("<td>").append( |                     .append($("<td>").append( | ||||||
|                         $(`<span class="bx bx-pen token-table-button" title="${t("etapi.rename_token")}"></span>`) |                         $(`<span class="bx bx-pen token-table-button" title="${t("etapi.rename_token")}"></span>`) | ||||||
|                             .on("click", () => this.renameToken(token.etapiTokenId, token.name)), |                             .on("click", () => this.renameToken(token.etapiTokenId, token.name)), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user