6e5f0bbe8d
31d geht jetzt wirklich über 31 Tage
104 lines
3.9 KiB
TypeScript
104 lines
3.9 KiB
TypeScript
import { RangeKey, Every } from '@/types/strom';
|
|
|
|
// 'raw' = 1-Sekunden-Rohdaten (measurement vzlogger) — aktuell, fuer 24h
|
|
// 'rollup' = stuendliche Snapshots (measurement arbeit_hourly) — schnell, fuer 7d/31d/365d
|
|
export type Source = 'raw' | 'rollup';
|
|
|
|
export interface ResolvedRange {
|
|
start: Date; // Beginn des sichtbaren Zeitraums (inklusiv)
|
|
stop: Date; // Ende des sichtbaren Zeitraums (exklusiv)
|
|
every: Every; // Fensterbreite je Balken
|
|
source: Source;
|
|
}
|
|
|
|
const HOUR_MS = 60 * 60 * 1000;
|
|
const DAY_MS = 24 * HOUR_MS;
|
|
|
|
/**
|
|
* Berechnet start/stop/every fuer ein Diagramm aus den Query-Parametern.
|
|
*
|
|
* - 24h: ohne date -> rollierend die letzten 24h ab jetzt (1 Balken/Stunde)
|
|
* mit date -> dieser Kalendertag 00:00-24:00
|
|
* - 7d: 7 Tage endend am gewaehlten Tag (Default heute), 1 Balken/Stunde
|
|
* - 31d: aktueller Monat (Default) -> rollierend die letzten 31 Tage endend heute;
|
|
* ein konkret gewaehlter (vergangener) Monat -> dieser Kalendermonat. 1 Balken/Tag
|
|
* - 365d: komplettes gewaehltes Jahr (Default aktuelles Jahr), 1 Balken/Tag
|
|
*/
|
|
export function resolveRange(
|
|
range: RangeKey,
|
|
params: { date?: string | null; month?: string | null; year?: string | null }
|
|
): ResolvedRange {
|
|
const now = new Date();
|
|
|
|
switch (range) {
|
|
case '24h': {
|
|
if (params.date) {
|
|
const start = startOfDay(params.date);
|
|
return { start, stop: new Date(start.getTime() + DAY_MS), every: '1h', source: 'raw' };
|
|
}
|
|
// rollierend: letzte 24h ab jetzt (Rohdaten = aktuellster Wert)
|
|
return { start: new Date(now.getTime() - 24 * HOUR_MS), stop: now, every: '1h', source: 'raw' };
|
|
}
|
|
|
|
case '7d': {
|
|
// Ende = Ende des gewaehlten Tages (Default heute)
|
|
const day = params.date ? startOfDay(params.date) : startOfDay(toDateString(now));
|
|
const stop = new Date(day.getTime() + DAY_MS);
|
|
return { start: new Date(stop.getTime() - 7 * DAY_MS), stop, every: '1h', source: 'rollup' };
|
|
}
|
|
|
|
case '31d': {
|
|
const { year, month } = params.month
|
|
? parseMonth(params.month)
|
|
: { year: now.getFullYear(), month: now.getMonth() };
|
|
|
|
// Default/laufender Monat: rollierend die letzten 31 Tage endend heute
|
|
// (analog zu 24h). Tagesgrenzen lokal via Datums-Arithmetik -> DST-sicher.
|
|
if (year === now.getFullYear() && month === now.getMonth()) {
|
|
const stop = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1); // Beginn morgen
|
|
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1 - 31);
|
|
return { start, stop, every: '1d', source: 'rollup' };
|
|
}
|
|
|
|
// Konkret gewaehlter (vergangener) Monat: kompletter Kalendermonat
|
|
const start = new Date(year, month, 1);
|
|
const stop = new Date(year, month + 1, 1);
|
|
return { start, stop, every: '1d', source: 'rollup' };
|
|
}
|
|
|
|
case '365d': {
|
|
// ein Balken pro Monat
|
|
const year = params.year ? parseInt(params.year, 10) : now.getFullYear();
|
|
const start = new Date(year, 0, 1);
|
|
const stop = new Date(year + 1, 0, 1);
|
|
return { start, stop, every: '1mo', source: 'rollup' };
|
|
}
|
|
}
|
|
}
|
|
|
|
function startOfDay(dateStr: string): Date {
|
|
const [y, m, d] = dateStr.split('-').map(Number);
|
|
return new Date(y, m - 1, d);
|
|
}
|
|
|
|
function parseMonth(monthStr: string): { year: number; month: number } {
|
|
const [y, m] = monthStr.split('-').map(Number);
|
|
return { year: y, month: m - 1 };
|
|
}
|
|
|
|
function toDateString(d: Date): string {
|
|
const y = d.getFullYear();
|
|
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
const day = String(d.getDate()).padStart(2, '0');
|
|
return `${y}-${m}-${day}`;
|
|
}
|
|
|
|
// Ein Fenster vor `d` (fuer den difference-Vorlauf). Monate kalendergenau.
|
|
export function windowStartBefore(d: Date, every: Every): Date {
|
|
const r = new Date(d);
|
|
if (every === '1h') r.setTime(r.getTime() - HOUR_MS);
|
|
else if (every === '1d') r.setTime(r.getTime() - DAY_MS);
|
|
else r.setMonth(r.getMonth() - 1); // '1mo'
|
|
return r;
|
|
}
|