feat: replace manual date formatting with formatDate/formatTime from i18n

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ulas
2026-03-31 23:24:21 +02:00
parent 3aefca0a44
commit 66a9bdfa44
6 changed files with 27 additions and 43 deletions
+2 -3
View File
@@ -8,7 +8,7 @@
import { api } from '/api.js'; import { api } from '/api.js';
import { openModal as openSharedModal, closeModal } from '/components/modal.js'; import { openModal as openSharedModal, closeModal } from '/components/modal.js';
import { stagger, vibrate } from '/utils/ux.js'; import { stagger, vibrate } from '/utils/ux.js';
import { t } from '/i18n.js'; import { t, formatDate } from '/i18n.js';
// -------------------------------------------------------- // --------------------------------------------------------
// Konstanten // Konstanten
@@ -324,8 +324,7 @@ function renderTrend(current, prev, prevLabel) {
} }
function formatEntryDate(dateStr) { function formatEntryDate(dateStr) {
const d = new Date(dateStr + 'T00:00:00'); return formatDate(new Date(dateStr + 'T00:00:00'));
return `${d.getDate().toString().padStart(2, '0')}.${(d.getMonth() + 1).toString().padStart(2, '0')}.`;
} }
// -------------------------------------------------------- // --------------------------------------------------------
+3 -8
View File
@@ -8,7 +8,7 @@ import { api } from '/api.js';
import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js'; import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js';
import { openModal as openSharedModal, closeModal } from '/components/modal.js'; import { openModal as openSharedModal, closeModal } from '/components/modal.js';
import { stagger } from '/utils/ux.js'; import { stagger } from '/utils/ux.js';
import { t } from '/i18n.js'; import { t, formatTime } from '/i18n.js';
// -------------------------------------------------------- // --------------------------------------------------------
// Konstanten // Konstanten
@@ -99,16 +99,11 @@ function formatDate(dateStr, { long = false, weekday = false } = {}) {
return `${day}. ${mon} ${d.getFullYear()}`; return `${day}. ${mon} ${d.getFullYear()}`;
} }
function formatTime(datetimeStr) {
if (!datetimeStr) return '';
const t = datetimeStr.slice(11, 16);
return t || '';
}
function formatDateTime(datetimeStr) { function formatDateTime(datetimeStr) {
if (!datetimeStr) return ''; if (!datetimeStr) return '';
const date = datetimeStr.slice(0, 10); 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); return time ? `${formatDate(date)} ${time} ${t('calendar.timeSuffix')}`.trimEnd() : formatDate(date);
} }
+10 -16
View File
@@ -5,7 +5,7 @@
*/ */
import { api } from '/api.js'; 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. // Hält den AbortController des aktuellen FAB-Listeners — wird bei jedem render() erneuert.
let _fabController = null; let _fabController = null;
@@ -21,12 +21,6 @@ function greeting(displayName) {
return t('dashboard.greetingEvening', { name: 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) { function formatDateTime(isoString) {
if (!isoString) return ''; if (!isoString) return '';
const d = new Date(isoString); const d = new Date(isoString);
@@ -35,12 +29,12 @@ function formatDateTime(isoString) {
tomorrow.setDate(today.getDate() + 1); tomorrow.setDate(today.getDate() + 1);
const dateStr = d.toDateString() === today.toDateString() const dateStr = d.toDateString() === today.toDateString()
? 'Heute' ? t('common.today')
: d.toDateString() === tomorrow.toDateString() : d.toDateString() === tomorrow.toDateString()
? 'Morgen' ? t('common.tomorrow')
: d.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }); : formatDate(d);
const timeStr = d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }); const timeStr = formatTime(d);
return `${dateStr}, ${timeStr} Uhr`; return `${dateStr}, ${timeStr} Uhr`;
} }
@@ -55,7 +49,7 @@ function formatDueDate(dateStr) {
if (diffH < 24) return { text: t('dashboard.dueSoon'), overdue: false }; if (diffH < 24) return { text: t('dashboard.dueSoon'), overdue: false };
if (diffH < 48) return { text: t('dashboard.dueTomorrow'), overdue: false }; if (diffH < 48) return { text: t('dashboard.dueTomorrow'), overdue: false };
return { return {
text: due.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit' }), text: formatDate(due),
overdue: false, overdue: false,
}; };
} }
@@ -142,7 +136,7 @@ function renderGreeting(user, stats = {}) {
<div class="widget-greeting"> <div class="widget-greeting">
<div class="widget-greeting__content"> <div class="widget-greeting__content">
<div class="widget-greeting__title">${greeting(user.display_name)}</div> <div class="widget-greeting__title">${greeting(user.display_name)}</div>
<div class="widget-greeting__date">${formatDate()}</div> <div class="widget-greeting__date">${formatDate(new Date())}</div>
${statChips.length ? `<div class="widget-greeting__chips">${statChips.join('')}</div>` : ''} ${statChips.length ? `<div class="widget-greeting__chips">${statChips.join('')}</div>` : ''}
</div> </div>
</div> </div>
@@ -197,7 +191,7 @@ function renderUpcomingEvents(events) {
const items = events.map((e) => { const items = events.map((e) => {
const d = new Date(e.start_datetime); const d = new Date(e.start_datetime);
const isToday = d.toDateString() === today; 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 ` return `
<div class="event-item" data-route="/calendar" role="button" tabindex="0"> <div class="event-item" data-route="/calendar" role="button" tabindex="0">
<div class="event-item__bar" style="background-color:${e.color || 'var(--color-accent)'}"></div> <div class="event-item__bar" style="background-color:${e.color || 'var(--color-accent)'}"></div>
@@ -278,7 +272,7 @@ function renderWeatherWidget(weather) {
const forecastHtml = forecast.map((d, i) => { const forecastHtml = forecast.map((d, i) => {
const date = new Date(d.date + 'T12:00:00'); 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' : ''; const extraCls = i >= 3 ? ' weather-forecast__day--extended' : '';
return ` return `
<div class="weather-forecast__day${extraCls}"> <div class="weather-forecast__day${extraCls}">
@@ -414,7 +408,7 @@ export async function render(container, { user }) {
<div class="widget-greeting" style="grid-column:1/-1"> <div class="widget-greeting" style="grid-column:1/-1">
<div class="widget-greeting__content"> <div class="widget-greeting__content">
<div class="widget-greeting__title">${greeting(user.display_name)}</div> <div class="widget-greeting__title">${greeting(user.display_name)}</div>
<div class="widget-greeting__date">${formatDate()}</div> <div class="widget-greeting__date">${formatDate(new Date())}</div>
</div> </div>
</div> </div>
${skeletonWidget(3)} ${skeletonWidget(3)}
+3 -8
View File
@@ -7,7 +7,7 @@
import { api } from '/api.js'; import { api } from '/api.js';
import { openModal as openSharedModal, closeModal as closeSharedModal } from '/components/modal.js'; import { openModal as openSharedModal, closeModal as closeSharedModal } from '/components/modal.js';
import { stagger } from '/utils/ux.js'; import { stagger } from '/utils/ux.js';
import { t } from '/i18n.js'; import { t, formatDate } from '/i18n.js';
// -------------------------------------------------------- // --------------------------------------------------------
// Konstanten // Konstanten
@@ -59,11 +59,7 @@ function addDays(dateStr, n) {
function formatWeekLabel(monday) { function formatWeekLabel(monday) {
const sunday = addDays(monday, 6); const sunday = addDays(monday, 6);
const fmt = (s) => { return `${formatDate(monday)} ${formatDate(sunday)}`;
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)}`;
} }
function isToday(dateStr) { function isToday(dateStr) {
@@ -71,8 +67,7 @@ function isToday(dateStr) {
} }
function formatDayDate(dateStr) { function formatDayDate(dateStr) {
const d = new Date(dateStr + 'T00:00:00Z'); return formatDate(dateStr);
return `${d.getUTCDate()}.${d.getUTCMonth() + 1}.`;
} }
// -------------------------------------------------------- // --------------------------------------------------------
+7 -6
View File
@@ -5,7 +5,7 @@
*/ */
import { api, auth } from '/api.js'; import { api, auth } from '/api.js';
import { t } from '/i18n.js'; import { t, formatDate, formatTime } from '/i18n.js';
/** /**
* @param {HTMLElement} container * @param {HTMLElement} container
@@ -34,13 +34,13 @@ export async function render(container, { user }) {
} catch (_) { /* non-critical */ } } catch (_) { /* non-critical */ }
const googleStatusText = googleStatus.connected 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'); : googleStatus.configured ? t('settings.notConnected') : t('settings.notConfigured');
const appleStatusText = appleStatus.connected 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.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'); : t('settings.notConnected');
container.innerHTML = ` container.innerHTML = `
@@ -499,9 +499,10 @@ function initials(name) {
return name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase(); return name.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase();
} }
function formatDate(iso) { function formatDateTime(iso) {
if (!iso) return ''; 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() { function currentTheme() {
+2 -2
View File
@@ -8,7 +8,7 @@ import { api } from '/api.js';
import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js'; import { renderRRuleFields, bindRRuleEvents, getRRuleValues } from '/rrule-ui.js';
import { openModal as openSharedModal, closeModal, wireBlurValidation, btnSuccess, btnError } from '/components/modal.js'; import { openModal as openSharedModal, closeModal, wireBlurValidation, btnSuccess, btnError } from '/components/modal.js';
import { stagger, vibrate } from '/utils/ux.js'; import { stagger, vibrate } from '/utils/ux.js';
import { t } from '/i18n.js'; import { t, formatDate } from '/i18n.js';
// -------------------------------------------------------- // --------------------------------------------------------
// Konstanten // 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.overdueDay', { count: Math.abs(diffDays) }), cls: 'due-date--overdue' };
if (diffDays === 0) return { label: t('tasks.dueToday'), cls: 'due-date--today' }; if (diffDays === 0) return { label: t('tasks.dueToday'), cls: 'due-date--today' };
if (diffDays === 1) return { label: t('tasks.dueTomorrow'), cls: '' }; 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) { function groupBy(tasks, mode) {