[racket] Library for date arithmetic?

From: John Clements (clements at brinckerhoff.org)
Date: Thu Mar 13 12:24:09 EDT 2014

On Mar 11, 2014, at 12:32 PM, Ismael Figueroa <ifigueroap at gmail.com> wrote:

> Working with a custom handin-server, I have a date value which represents a deadline, but I also want to allow late submission up to 3 days later than that (well, an arbitrary number of days). Hence, I need to check whether the current date is at most 3 days later than the first one.
> In the configuration file I read a custom entry for the deadline, indicating year, month, day, hours, minutes and seconds. Then I guess I could do:
> (define d      (seconds->date (find-seconds seconds minutes hours day month year)))
> (define d+1 (seconds->date (find-seconds seconds minutes hours (+ day 1) month year))
> (define d+2 (seconds->date (find-seconds seconds minutes hours (+ day 2) month year))
> (define d+3 (seconds->date (find-seconds seconds minutes hours (+ day 3) month year))
> And then do a comparison, like
> (let ([now (current-seconds)])
>    (or (> now (date->seconds d)) (> now (date->seconds d+1) ...))
> But this looks too low level to me, and surprisingly the utilities provided by racket/date are somewhat sparse.
> Does anyone know about a higher-level library for manipulating dates, and performing arithmetic comparisons and operations? 

Dates are harder than they look.  In this case, for instance, I think it would be a bad idea to add to the “day” without checking that the result is a legal date. However, in this (and many other) instance(s), it seems like you can get nearly everything you want simply by holding off on the “seconds->date” call.

#lang racket

(define DAY-SECONDS 86400)

(define d   (find-seconds seconds minutes hours day month year))
(define d+1 (+ d (* 1 DAY-SECONDS)))
(define d+2 (+ d (* 2 DAY-SECONDS)))
(define d+3 (+ d (* 3 DAY-SECONDS)))

;;And then do a comparison, like

(let ([now (current-seconds)])
   (cond [(< now d) "on time!"]
         [(< now d+1) "one day late!"]
         [(< now d+2) "two days late!"]))

Posted on the users mailing list.