diff --git a/public/pages/budget.js b/public/pages/budget.js index daa5db0..8ce33f1 100644 --- a/public/pages/budget.js +++ b/public/pages/budget.js @@ -8,7 +8,7 @@ import { api } from '/api.js'; import { openModal as openSharedModal, closeModal } from '/components/modal.js'; import { stagger, vibrate } from '/utils/ux.js'; -import { t } from '/i18n.js'; +import { t, formatDate } from '/i18n.js'; // -------------------------------------------------------- // Konstanten @@ -324,8 +324,7 @@ function renderTrend(current, prev, prevLabel) { } function formatEntryDate(dateStr) { - const d = new Date(dateStr + 'T00:00:00'); - return `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth() + 1).toString().padStart(2, '0')}.`; + return formatDate(new Date(dateStr + 'T00:00:00')); } // -------------------------------------------------------- diff --git a/public/pages/calendar.js b/public/pages/calendar.js index 7c6e91e..298e488 100644 --- a/public/pages/calendar.js +++ b/public/pages/calendar.js @@ -8,7 +8,7 @@ import { api } from '/api.js'; import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js'; import { openModal as openSharedModal, closeModal } from '/components/modal.js'; import { stagger } from '/utils/ux.js'; -import { t } from '/i18n.js'; +import { t, formatTime } from '/i18n.js'; // -------------------------------------------------------- // Konstanten @@ -99,16 +99,11 @@ function formatDate(dateStr, { long = false, weekday = false } = {}) { return `${day}. ${mon} ${d.getFullYear()}`; } -function formatTime(datetimeStr) { - if (!datetimeStr) return ''; - const t = datetimeStr.slice(11, 16); - return t || ''; -} - function formatDateTime(datetimeStr) { if (!datetimeStr) return ''; const date = datetimeStr.slice(0, 10); - const time = datetimeStr.slice(11, 16); + const hasTime = datetimeStr.length > 10 && datetimeStr.slice(11, 16).trim() !== ''; + const time = hasTime ? formatTime(datetimeStr) : ''; return time ? `${formatDate(date)} ${time} ${t('calendar.timeSuffix')}`.trimEnd() : formatDate(date); } diff --git a/public/pages/dashboard.js b/public/pages/dashboard.js index 855a265..6200145 100644 --- a/public/pages/dashboard.js +++ b/public/pages/dashboard.js @@ -5,7 +5,7 @@ */ import { api } from '/api.js'; -import { t } from '/i18n.js'; +import { t, formatDate, formatTime, getLocale } from '/i18n.js'; // Hält den AbortController des aktuellen FAB-Listeners — wird bei jedem render() erneuert. let _fabController = null; @@ -21,12 +21,6 @@ function greeting(displayName) { return t('dashboard.greetingEvening', { name: displayName }); } -function formatDate(date = new Date()) { - return date.toLocaleDateString('de-DE', { - weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', - }); -} - function formatDateTime(isoString) { if (!isoString) return ''; const d = new Date(isoString); @@ -35,12 +29,12 @@ function formatDateTime(isoString) { tomorrow.setDate(today.getDate() + 1); const dateStr = d.toDateString() === today.toDateString() - ? 'Heute' + ? t('common.today') : d.toDateString() === tomorrow.toDateString() - ? 'Morgen' - : d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }); + ? t('common.tomorrow') + : formatDate(d); - const timeStr = d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); + const timeStr = formatTime(d); return `${dateStr}, ${timeStr} Uhr`; } @@ -55,7 +49,7 @@ function formatDueDate(dateStr) { if (diffH < 24) return { text: t('dashboard.dueSoon'), overdue: false }; if (diffH < 48) return { text: t('dashboard.dueTomorrow'), overdue: false }; return { - text: due.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }), + text: formatDate(due), overdue: false, }; } @@ -142,7 +136,7 @@ function renderGreeting(user, stats = {}) {
${greeting(user.display_name)}
-
${formatDate()}
+
${formatDate(new Date())}
${statChips.length ? `
${statChips.join('')}
` : ''}
@@ -197,7 +191,7 @@ function renderUpcomingEvents(events) { const items = events.map((e) => { const d = new Date(e.start_datetime); const isToday = d.toDateString() === today; - const timeStr = e.all_day ? t('dashboard.allDay') : d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr'; + const timeStr = e.all_day ? t('dashboard.allDay') : formatTime(d) + ' Uhr'; return `
@@ -278,7 +272,7 @@ function renderWeatherWidget(weather) { const forecastHtml = forecast.map((d, i) => { const date = new Date(d.date + 'T12:00:00'); - const label = date.toLocaleDateString('de-DE', { weekday: 'short' }); + const label = new Intl.DateTimeFormat(getLocale(), { weekday: 'short' }).format(date); const extraCls = i >= 3 ? ' weather-forecast__day--extended' : ''; return `
@@ -414,7 +408,7 @@ export async function render(container, { user }) {
${greeting(user.display_name)}
-
${formatDate()}
+
${formatDate(new Date())}
${skeletonWidget(3)} diff --git a/public/pages/meals.js b/public/pages/meals.js index 7917379..54e9883 100644 --- a/public/pages/meals.js +++ b/public/pages/meals.js @@ -7,7 +7,7 @@ import { api } from '/api.js'; import { openModal as openSharedModal, closeModal as closeSharedModal } from '/components/modal.js'; import { stagger } from '/utils/ux.js'; -import { t } from '/i18n.js'; +import { t, formatDate } from '/i18n.js'; // -------------------------------------------------------- // Konstanten @@ -59,11 +59,7 @@ function addDays(dateStr, n) { function formatWeekLabel(monday) { const sunday = addDays(monday, 6); - const fmt = (s) => { - const d = new Date(s + 'T00:00:00Z'); - return `${d.getUTCDate().toString().padStart(2, '0')}.${(d.getUTCMonth() + 1).toString().padStart(2, '0')}.${d.getUTCFullYear()}`; - }; - return `${fmt(monday)} – ${fmt(sunday)}`; + return `${formatDate(monday)} – ${formatDate(sunday)}`; } function isToday(dateStr) { @@ -71,8 +67,7 @@ function isToday(dateStr) { } function formatDayDate(dateStr) { - const d = new Date(dateStr + 'T00:00:00Z'); - return `${d.getUTCDate()}.${d.getUTCMonth() + 1}.`; + return formatDate(dateStr); } // -------------------------------------------------------- diff --git a/public/pages/settings.js b/public/pages/settings.js index 66c2423..03a15d5 100644 --- a/public/pages/settings.js +++ b/public/pages/settings.js @@ -5,7 +5,7 @@ */ import { api, auth } from '/api.js'; -import { t } from '/i18n.js'; +import { t, formatDate, formatTime } from '/i18n.js'; /** * @param {HTMLElement} container @@ -34,13 +34,13 @@ export async function render(container, { user }) { } catch (_) { /* non-critical */ } const googleStatusText = googleStatus.connected - ? (googleStatus.lastSync ? t('settings.connectedLastSync', { date: formatDate(googleStatus.lastSync) }) : t('settings.connected')) + ? (googleStatus.lastSync ? t('settings.connectedLastSync', { date: formatDateTime(googleStatus.lastSync) }) : t('settings.connected')) : googleStatus.configured ? t('settings.notConnected') : t('settings.notConfigured'); const appleStatusText = appleStatus.connected - ? (appleStatus.lastSync ? t('settings.connectedLastSync', { date: formatDate(appleStatus.lastSync) }) : t('settings.connected')) + ? (appleStatus.lastSync ? t('settings.connectedLastSync', { date: formatDateTime(appleStatus.lastSync) }) : t('settings.connected')) : appleStatus.configured - ? (appleStatus.lastSync ? t('settings.configuredLastSync', { date: formatDate(appleStatus.lastSync) }) : t('settings.configured')) + ? (appleStatus.lastSync ? t('settings.configuredLastSync', { date: formatDateTime(appleStatus.lastSync) }) : t('settings.configured')) : t('settings.notConnected'); container.innerHTML = ` @@ -499,9 +499,10 @@ function initials(name) { return name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase(); } -function formatDate(iso) { +function formatDateTime(iso) { if (!iso) return ''; - return new Date(iso).toLocaleString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); + const d = new Date(iso); + return `${formatDate(d)} ${formatTime(d)}`.trim(); } function currentTheme() { diff --git a/public/pages/tasks.js b/public/pages/tasks.js index cee4b8a..4621be7 100644 --- a/public/pages/tasks.js +++ b/public/pages/tasks.js @@ -8,7 +8,7 @@ import { api } from '/api.js'; import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js'; import { openModal as openSharedModal, closeModal, wireBlurValidation, btnSuccess, btnError } from '/components/modal.js'; import { stagger, vibrate } from '/utils/ux.js'; -import { t } from '/i18n.js'; +import { t, formatDate } from '/i18n.js'; // -------------------------------------------------------- // Konstanten @@ -64,7 +64,7 @@ function formatDueDate(dateStr) { if (diffDays < 0) return { label: t('tasks.overdueDay', { count: Math.abs(diffDays) }), cls: 'due-date--overdue' }; if (diffDays === 0) return { label: t('tasks.dueToday'), cls: 'due-date--today' }; if (diffDays === 1) return { label: t('tasks.dueTomorrow'), cls: '' }; - return { label: due.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }), cls: '' }; + return { label: formatDate(due), cls: '' }; } function groupBy(tasks, mode) {