cripslock

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit bb67cbd0be3ef1a6f9dcd853cf5487e40ec2851b
parent 1a6f46969766f5a10f71de9df955e9345f63e9c3
Author: Daniel Barlow <dan@telent.net>
Date:   Sat, 19 Jul 2025 23:57:33 +0100

timestamp parsing

Diffstat:
Mmain.fnl | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+), 0 deletions(-)

diff --git a/main.fnl b/main.fnl @@ -24,6 +24,67 @@ (expect= (stream:read "l") "first content line")))) +;; there are two date formats used in most of the extant posts: +;; "Fri Jun 29 14:17:56 2018" (emacs current-time-string) +;; and "Fri, 18 Oct 2013 10:18:34 +0100" (*rfc2822") + +(local months + {"jan" 1 + "feb" 2 + "mar" 3 + "apr" 4 + "may" 5 + "jun" 6 + "jul" 7 + "aug" 8 + "sep" 9 + "oct" 10 + "nov" 11 + "dec" 12 + }) + +(fn parse-rfc2822-timestamp [date-str] + (let [(s _ weekday day month year hour min sec offset) + (string.find date-str "(%a+), (%d+) (%a+) (%d+) (%d+):(%d+):(%d+) ([+-]%d+)" 1)] + (and s + (os.time { + : year + :month (. months (string.lower month)) + : day + : hour + : min + : sec + :isdst (not (= offset "+0000")) ;; massive cheating here + })))) + +(fn parse-emacs-timestamp [date-str] + (let [(s _ weekday month day hour min sec year) + (string.find date-str "(%a+) (%a+) (%d+) (%d+):(%d+):(%d+) (%d+)" 1)] + (and s + (os.time { + : year + :month (. months (string.lower month)) + : day + : hour + : min + : sec + :isdst true ; probably? + })))) + +(fn parse-timestamp [s] + (or (parse-rfc2822-timestamp s) + (parse-emacs-timestamp s))) + +(define-tests :date-parsing + (expect= (parse-rfc2822-timestamp "Fri, 18 Oct 2013 10:18:34 +0100") + 1382087914) + (expect= (parse-rfc2822-timestamp "Tue, 28 Dec 2004 21:41:24 +0000") + 1104270084) + (expect= (parse-emacs-timestamp "Sat Jul 19 23:53:21 2025") 1752965601) + (expect= (parse-rfc2822-timestamp "Sat Jul 19 23:53:21 2025") nil) + (expect= (parse-timestamp "Sat Jul 19 23:53:21 2025") 1752965601) + ) + (fn index-posts [path] (collect [name (lfs.dir path)] (let [fullname (.. path "/" name)