first version
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
||||
// Small time/date helpers shared by popup, dashboard and planner.
|
||||
// Times of day are handled as "minutes since midnight", durations as minutes.
|
||||
var U = (() => {
|
||||
const pad = (n) => String(n).padStart(2, '0');
|
||||
|
||||
const toMin = (hhmm) => {
|
||||
const m = /^(\d{1,2})[:.h](\d{2})$/.exec(String(hhmm || '').trim());
|
||||
return m ? +m[1] * 60 + +m[2] : null;
|
||||
};
|
||||
|
||||
const fmtTime = (min) => `${pad(Math.floor(min / 60))}:${pad(min % 60)}`;
|
||||
|
||||
const fmtDur = (min) => {
|
||||
const sign = min < 0 ? '-' : '';
|
||||
min = Math.abs(Math.round(min));
|
||||
return `${sign}${Math.floor(min / 60)}:${pad(min % 60)}`;
|
||||
};
|
||||
|
||||
// "1", "1.5", "1,5", "1:30", "90m", "1h30" -> minutes. Empty -> null.
|
||||
const parseHours = (s) => {
|
||||
s = String(s ?? '').trim().toLowerCase();
|
||||
if (!s) return null;
|
||||
let m;
|
||||
if ((m = /^(\d+)\s*m(in)?$/.exec(s))) return +m[1];
|
||||
if ((m = /^(\d+)\s*[:h]\s*(\d{1,2})?\s*m?(in)?$/.exec(s))) return +m[1] * 60 + +(m[2] || 0);
|
||||
if ((m = /^(\d+(?:[.,]\d+)?)$/.exec(s))) return Math.round(parseFloat(m[1].replace(',', '.')) * 60);
|
||||
return null;
|
||||
};
|
||||
|
||||
const parseDate = (iso) => {
|
||||
const [y, m, d] = iso.split('-').map(Number);
|
||||
return new Date(y, m - 1, d);
|
||||
};
|
||||
|
||||
const isoDate = (dt) => `${dt.getFullYear()}-${pad(dt.getMonth() + 1)}-${pad(dt.getDate())}`;
|
||||
|
||||
const addDays = (iso, n) => {
|
||||
const dt = parseDate(iso);
|
||||
dt.setDate(dt.getDate() + n);
|
||||
return isoDate(dt);
|
||||
};
|
||||
|
||||
// ISO weekday: 1 = Monday ... 7 = Sunday
|
||||
const weekday = (iso) => parseDate(iso).getDay() || 7;
|
||||
|
||||
const WEEKDAYS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
|
||||
const weekdayName = (iso) => WEEKDAYS[weekday(iso) - 1];
|
||||
|
||||
// Monday of the week containing iso
|
||||
const monday = (iso) => addDays(iso, 1 - weekday(iso));
|
||||
|
||||
const weeksBetween = (a, b) =>
|
||||
Math.round((parseDate(monday(b)) - parseDate(monday(a))) / (7 * 864e5));
|
||||
|
||||
// Kimai wants HTML5 local datetime: 2026-10-07T08:00:00
|
||||
const kimaiDateTime = (iso, min) => `${iso}T${fmtTime(min)}:00`;
|
||||
|
||||
const uid = () => Math.random().toString(36).slice(2, 10);
|
||||
|
||||
return {
|
||||
pad, toMin, fmtTime, fmtDur, parseHours, parseDate, isoDate, addDays,
|
||||
weekday, weekdayName, WEEKDAYS, monday, weeksBetween, kimaiDateTime, uid,
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user