calendar
All repositories: gitoria
2.5 KB
// dates.hl — plain date / text helpers shared by the server (events.hl) and the month view in the browser.// No plugins, no Date (hl:time has no time zones): dates are 'YYYY-MM-DD' texts, times 'HH:MM'.static isText = (v) => { return v != null && hlTypeName(v) == 'String' }static digitsAt = (s, at, n) => {if (s.length < at + n) { return false }let i = atwhile (i < at + n) {let c = s.charCodeAt(i)if (c < 48 || c > 57) { return false }i = i + 1}return true}static leap = (y) => { return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 }static daysIn = (y, m) => {if (m == 2) { return leap(y) ? 29 : 28 }if (m == 4 || m == 6 || m == 9 || m == 11) { return 30 }return 31}static pad = (n) => { return n < 10 ? '0' + n : '' + n }// 'YYYY-MM-DD' that is a real daystatic isDate = (s) => {if (!isText(s) || s.length != 10 || s[4] != '-' || s[7] != '-') { return false }if (!digitsAt(s, 0, 4) || !digitsAt(s, 5, 2) || !digitsAt(s, 8, 2)) { return false }let y = toNumber(s.slice(0, 4))let m = toNumber(s.slice(5, 7))let d = toNumber(s.slice(8, 10))return y >= 1 && m >= 1 && m <= 12 && d >= 1 && d <= daysIn(y, m)}// 'HH:MM'static isTime = (s) => {if (!isText(s) || s.length != 5 || s[2] != ':' || !digitsAt(s, 0, 2) || !digitsAt(s, 3, 2)) { return false }return toNumber(s.slice(0, 2)) < 24 && toNumber(s.slice(3, 5)) < 60}static nextDay = (s) => {let y = toNumber(s.slice(0, 4))let m = toNumber(s.slice(5, 7))let d = toNumber(s.slice(8, 10))if (d < daysIn(y, m)) { return s.slice(0, 8) + pad(d + 1) }if (m < 12) { return s.slice(0, 5) + pad(m + 1) + '-01' }return pad(y) + '-01-01'}static prevDay = (s) => {let y = toNumber(s.slice(0, 4))let m = toNumber(s.slice(5, 7))let d = toNumber(s.slice(8, 10))if (d > 1) { return s.slice(0, 8) + pad(d - 1) }if (m > 1) { return s.slice(0, 5) + pad(m - 1) + '-' + pad(daysIn(y, m - 1)) }return pad(y - 1) + '-12-31'}// a time zone name from the browser: letters, digits and _ / + - onlystatic isZone = (s) => {if (!isText(s) || s.length < 1 || s.length > 64) { return false }let i = 0while (i < s.length) {let c = s.charCodeAt(i)let ok = (c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c == 95 || c == 47 || c == 43 || c == 45if (!ok) { return false }i = i + 1}return true}// a < b for equal-format ISO texts (hybriel #2: no ordering on strings)static before = (a, b) => {let i = 0while (i < a.length && i < b.length) {let x = a.charCodeAt(i)let y = b.charCodeAt(i)if (x != y) { return x < y }i = i + 1}return a.length < b.length}
Branches
- mainmain branch
Latest commits
- f5ce6b1dcalendar mission 001 (2/4): code order — topics, map, thin faces: lib/util.hl, lib/events(-helpers).hl (+calendarView/settingsView/soonOf), lib/settings.hl, lib/users.hl (+userOfLoginCode, tagOf), lib/api(-helpers).hl; project.hl = map; login route takes &req/&sessions (failed-login reason now kept); gates 78/0 + 18/0mre
- c6fbd011calendar mission 001 (1/4): code order — files moved: lib/events.hl, lib/users.hl, components/styles.hl (imports only); gates 78/0 + 18/0, live-data run identicalmre
- d6c59290calendar: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); gates 78/0 + 18/0mre
- 7bd0337ccalendar: Hybriel master 190aa11d (fc838894 GC correctness, #126 closure scopes, #127); gates 78/0 + 18/0mre
- ff41310ccalendar: Hybriel master 8efba065 (#126 memory, #48 lambda copy; audit: no & needed)mre
- 14ba08c7antcolony#40: mission references point to the moved missionsmre
- 99c73346antcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 76edaa62calendar: Hybriel master ff51cf46 (re-vendor round, static workaround removed)mre
- 90a3fc2cdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- 6722b72ddeploy.sh: never send .git or .gitignore to Byrodinmre
- be099807State of 2026-09-27, before the move to gitoriamre