>> How can I subtract 22 days from (current-time) using SRFI-19? > Note that the above example suggests that ‘string->duration’ returns a > time object with of type ‘time-duration’ (thus independent of the > current time.) Ah, OK. But we’ll have to subtract from (current-time) later anyway, right? Why do you want to return a ‘time-duration’ object? So, here’s the parsing phase. WDYT? (use-modules (srfi srfi-1) (srfi srfi-19) (ice-9 regex)) ;;; ;;; Parsing. ;;; (define (string->generations str) (define (maybe-integer) (let ((x (string->number str))) (and (integer? x) (list x)))) (define (maybe-comma-separated-integers) (let ((lst (delete-duplicates (map string->number (delete "" (string-split str #\,)))))) (and (every integer? lst) lst))) (define (safe-match:substring->number match n) (false-if-exception (string->number (match:substring match n)))) (define (maybe-whole-range) (let* ((rx (make-regexp "^([0-9]+)\\.\\.([0-9]+)$")) (res (regexp-exec rx str)) (x (safe-match:substring->number res 1)) (y (safe-match:substring->number res 2))) (and (every integer? (list x y)) (<= x y) (iota (1+ (- y x)) x)))) (define (maybe-start-range) (let* ((rx (make-regexp "^([0-9]+)\\.\\.$")) (res (regexp-exec rx str)) (x (safe-match:substring->number res 1))) (and (integer? x) `(>= ,x)))) (define (maybe-end-range) (let* ((rx (make-regexp "^\\.\\.([0-9]+)$")) (res (regexp-exec rx str)) (x (safe-match:substring->number res 1))) (and (integer? x) `(<= ,x)))) (or (maybe-integer) (maybe-comma-separated-integers) (maybe-whole-range) (maybe-start-range) (maybe-end-range))) (define (string->duration str) (define (maybe-duration hours pattern) (let ((res (regexp-exec (make-regexp pattern) str))) (false-if-exception (make-time time-duration 0 (* 3600 hours (string->number (match:substring res 1))))))) (define (days) (maybe-duration 24 "^([0-9]+)d$")) (define (weeks) (maybe-duration (* 24 7) "^([0-9]+)w$")) (define (months) (maybe-duration (* 24 30) "^([0-9]+)m$")) (or (days) (weeks) (months)))