new features, bookstack

This commit is contained in:
Matthias Hochmeister
2026-03-03 21:30:38 +01:00
parent 817329db70
commit d3561c1109
32 changed files with 1923 additions and 207 deletions

View File

@@ -0,0 +1,60 @@
/**
* Shared utilities for German date format (DD.MM.YYYY / DD.MM.YYYY HH:MM)
* Used as plain TextField inputs with placeholder instead of type="date"/"datetime-local"
*/
/** ISO/YYYY-MM-DD → DD.MM.YYYY */
export function toGermanDate(iso: string | null | undefined): string {
if (!iso) return '';
// Already DD.MM.YYYY
if (/^\d{2}\.\d{2}\.\d{4}$/.test(iso)) return iso;
// YYYY-MM-DD (possibly with time)
const m = iso.match(/^(\d{4})-(\d{2})-(\d{2})/);
if (m) return `${m[3]}.${m[2]}.${m[1]}`;
return '';
}
/** ISO datetime → DD.MM.YYYY HH:MM */
export function toGermanDateTime(iso: string | null | undefined): string {
if (!iso) return '';
// Already DD.MM.YYYY HH:MM
if (/^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}$/.test(iso)) return iso;
// YYYY-MM-DDTHH:MM or YYYY-MM-DD HH:MM
const m = iso.match(/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})/);
if (m) return `${m[3]}.${m[2]}.${m[1]} ${m[4]}:${m[5]}`;
// Date only → midnight
const d = iso.match(/^(\d{4})-(\d{2})-(\d{2})$/);
if (d) return `${d[3]}.${d[2]}.${d[1]} 00:00`;
return '';
}
/** DD.MM.YYYY → YYYY-MM-DD (ISO date string) */
export function fromGermanDate(german: string): string {
const m = german.match(/^(\d{2})\.(\d{2})\.(\d{4})$/);
if (!m) return '';
return `${m[3]}-${m[2]}-${m[1]}`;
}
/** DD.MM.YYYY HH:MM → ISO datetime string (YYYY-MM-DDTHH:MM:00.000Z local) */
export function fromGermanDateTime(german: string): string {
const m = german.match(/^(\d{2})\.(\d{2})\.(\d{4}) (\d{2}):(\d{2})$/);
if (!m) return '';
return `${m[3]}-${m[2]}-${m[1]}T${m[4]}:${m[5]}`;
}
/** Validates DD.MM.YYYY format and that the date is valid */
export function isValidGermanDate(value: string): boolean {
if (!/^\d{2}\.\d{2}\.\d{4}$/.test(value)) return false;
const [dd, mm, yyyy] = value.split('.').map(Number);
const date = new Date(yyyy, mm - 1, dd);
return date.getFullYear() === yyyy && date.getMonth() === mm - 1 && date.getDate() === dd;
}
/** Validates DD.MM.YYYY HH:MM format */
export function isValidGermanDateTime(value: string): boolean {
if (!/^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}$/.test(value)) return false;
const [datePart, timePart] = value.split(' ');
const [hh, mm] = timePart.split(':').map(Number);
if (hh > 23 || mm > 59) return false;
return isValidGermanDate(datePart);
}