Initiale Arbeitszeiterfassung (Next.js 16 + SQLite)
Web-App zur Erfassung der Arbeitszeit, Layout/Architektur an Projekt logbuch angelehnt, mit grüner Grundfarbe und SQLite3 statt MySQL. - Eingabemaske: Datum (mit Wochentag), Ort (Kunde FFM/Homeoffice/Andrena), Beginn/Ende, Reisezeit, Vertriebsunterstützung (default 2h), Kommentar (max 500) - Berechnung: Arbeitszeit = Ende-Beginn; Mehrarbeit = Arbeitszeit - 8h - Pause - Pause als globale Einstellung (Einstellungen-Tab) - Tabs Eingabe/Liste/Einstellungen, letzte 10 Einträge unter der Maske - Single-User-Login (Benutzer Birgit + Passwort fest in .env), JWT-Cookie via jose - better-sqlite3, Docker-Setup für docker.citysensor.de Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
// Reine Hilfsfunktionen für Datum-/Zeit-Berechnungen (ohne DB-Zugriff).
|
||||
|
||||
const WOCHENTAGE = [
|
||||
'Sonntag',
|
||||
'Montag',
|
||||
'Dienstag',
|
||||
'Mittwoch',
|
||||
'Donnerstag',
|
||||
'Freitag',
|
||||
'Samstag',
|
||||
];
|
||||
|
||||
/** "HH:MM" → Minuten seit Mitternacht, oder null bei ungültiger Eingabe. */
|
||||
export function parseHM(hm: string): number | null {
|
||||
const m = /^(\d{1,2}):(\d{2})$/.exec(hm ?? '');
|
||||
if (!m) return null;
|
||||
const h = Number(m[1]);
|
||||
const min = Number(m[2]);
|
||||
if (h < 0 || h > 23 || min < 0 || min > 59) return null;
|
||||
return h * 60 + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Differenz zwischen Beginn und Ende in dezimalen Stunden.
|
||||
* Gibt 0 zurück, wenn eine Zeit ungültig ist. Ende vor Beginn ⇒ 0.
|
||||
*/
|
||||
export function toDecimalHours(beginn: string, ende: string): number {
|
||||
const b = parseHM(beginn);
|
||||
const e = parseHM(ende);
|
||||
if (b === null || e === null) return 0;
|
||||
const diff = e - b;
|
||||
if (diff <= 0) return 0;
|
||||
return diff / 60;
|
||||
}
|
||||
|
||||
/** Mehrarbeit = Arbeitszeit − 8 Stunden − Pause (kann negativ sein). */
|
||||
export function mehrarbeit(arbeitszeitStd: number, pauseStd: number): number {
|
||||
return arbeitszeitStd - 8 - pauseStd;
|
||||
}
|
||||
|
||||
/** Deutscher Wochentagsname für ein "YYYY-MM-DD"-Datum, oder "" bei ungültig. */
|
||||
export function weekdayName(datum: string): string {
|
||||
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(datum ?? '');
|
||||
if (!m) return '';
|
||||
const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
|
||||
if (isNaN(d.getTime())) return '';
|
||||
return WOCHENTAGE[d.getDay()];
|
||||
}
|
||||
|
||||
/** Dezimalstunden deutsch formatieren, z.B. 0.5 → "0,5". */
|
||||
export function formatHours(value: number): string {
|
||||
return value.toLocaleString('de-DE', {
|
||||
minimumFractionDigits: 1,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user