Weather Station / ECOWITT / DNT
0

Configure Feed

Select the types of activity you want to include in your feed.

at stats2.0 2.7 kB View raw
1/** 2 * Represents the time resolution for data aggregation. 3 */ 4export type Resolution = "minute" | "hour" | "day"; 5 6/** 7 * Parses a timestamp string into a Date object. 8 * Handles formats like "YYYY/M/D H:mm" or "YYYY-M-DTH:mm:ss". 9 * @param {string} ts - The timestamp string to parse. 10 * @returns {Date | null} A Date object, or null if parsing fails. 11 */ 12export function parseTimestamp(ts: string): Date | null { 13 // Expected like: 2025/8/1 0:03 (no zero padding guaranteed) 14 if (!ts) return null; 15 const [datePart, timePart] = ts.trim().split(/[\sT]+/); 16 if (!datePart) return null; 17 const dateSep = datePart.includes("-") ? "-" : "/"; 18 const [y, m, d] = datePart.split(dateSep).map((s) => Number(s)); 19 let hh = 0, mm = 0, ss = 0; 20 if (timePart) { 21 const [h, m2, s2] = timePart.split(":"); 22 hh = Number(h ?? 0); 23 mm = Number(m2 ?? 0); 24 ss = Number(s2 ?? 0); 25 } 26 if (!Number.isFinite(y) || !Number.isFinite(m) || !Number.isFinite(d)) return null; 27 return new Date(y, (m || 1) - 1, d || 1, hh, mm, ss, 0); 28} 29 30/** 31 * Floors a date to the specified resolution. 32 * @param {Date} dt - The date to floor. 33 * @param {Resolution} res - The resolution ("minute", "hour", or "day"). 34 * @returns {Date} The floored date. 35 */ 36export function floorToResolution(dt: Date, res: Resolution): Date { 37 const d = new Date(dt.getTime()); 38 if (res === "day") { 39 d.setHours(0, 0, 0, 0); 40 } else if (res === "hour") { 41 d.setMinutes(0, 0, 0); 42 } else { 43 d.setSeconds(0, 0); 44 } 45 return d; 46} 47 48/** 49 * Creates a string key for a date based on the specified resolution. 50 * @param {Date} dt - The date to create a key for. 51 * @param {Resolution} res - The resolution. 52 * @returns {string} The formatted key string. 53 */ 54export function keyForResolution(dt: Date, res: Resolution): string { 55 const y = dt.getFullYear(); 56 const m = dt.getMonth() + 1; 57 const d = dt.getDate(); 58 const hh = dt.getHours(); 59 const mm = dt.getMinutes(); 60 if (res === "day") return `${y}-${pad(m)}-${pad(d)}`; 61 if (res === "hour") return `${y}-${pad(m)}-${pad(d)} ${pad(hh)}:00`; 62 return `${y}-${pad(m)}-${pad(d)} ${pad(hh)}:${pad(mm)}`; 63} 64 65/** 66 * Pads a number with a leading zero if it is less than 10. 67 * @param {number} n - The number to pad. 68 * @returns {string} The padded string. 69 * @private 70 */ 71function pad(n: number): string { return n < 10 ? `0${n}` : String(n); } 72 73/** 74 * Converts a Date object to an ISO string, adjusted for the local timezone. 75 * @param {Date} dt - The date to convert. 76 * @returns {string} The ISO string. 77 */ 78export function iso(dt: Date): string { 79 return new Date(dt.getTime() - dt.getTimezoneOffset() * 60000).toISOString(); 80}