Racket Lang – Dates

Racket

I’ve finally wrapped my head around a functional programming language: Racket. I tried Common Lisp but it just wasn’t clicking. Enter Racket. Racket specifically aims itself at learners, students, teachers, as well as professionals. It has excellent documentation and comes with free textbooks for class or self-study. Racket made functional programming click for me.

For the below, I’m assuming you’re at least a little familiar with Racket. I’ll post an intro later.

Dates

Working with dates in any language is a bit of a pain, and Racket is no different. Racket provides the racket/date package, but it’s only mildly useful. The documentation points to both “the Gregor” 3rd party date/time package, and “srfi 19”.

SRFI

Being new to Racket, I had to look up srfi 19. SRFI stands for Scheme Requests for Implementation, and are community proposals of functionality to be included into the core language. Some SRFIs are provided as libraries. You include SRFIs as such:

(require srfi/n)

With n being the SRFI number, which in our case is 19.

The Gregor

The Gregor seems useful, but srfi seems a bit more built-in.

My Use-Case

I’m writing a simple console dice game that interfaces with sqlite3, and I need to be able to compare dates irregardless of the time. For instance 13 February 2026 is less than 22 March 2026. There’s no real dates comparision in the core language, so I rolled my own predicate function.

Here’s what I came up with:

#lang racket
(require srfi/19)
(define date1 (string->date "4-1-26" "~d-~m-~y"))
(define date2 (string->date "4-2-26" "~d-~m-~y"))
(define date3 (string->date "1-1-27" "~d-~m-~y"))

;; return magnitude of two dates (greater, equal, or less-than)
(define (date-magnitude date1 date2)
  (cond
    [(> date1 date2) 1]
    [(= date1 date2) 0]
    [(< date1 date2) -1]))

;; calculate if date1 > date2, irregardless of time
(define (date>? date1 date2)
  (let ([year-mag (date-magnitude (date-year date1) (date-year date2))]
        [month-mag (date-magnitude (date-month date1) (date-month date2))]
        [day-mag (date-magnitude (date-day date1) (date-day date2))])
    (cond
      [(= year-mag 1) #t]
      [(= year-mag -1) #f]
      [(and (= year-mag 0) (= month-mag 1)) #t]
      [(and (= year-mag 0) (= month-mag -1)) #f]
      [(and (= year-mag 0) (= month-mag 0) (= day-mag 1) #t)]
      [else #f])))

Discussion

SRFI is only needed for the string->date functions, which I use here for ease of testing in Dr Racket’s console.

For two dates, the magnitude maps <, =, > to -1, 0, 1 respectively.

With regards to comparing date1 to date2:

The cond says: if the year is greater, return true, if less, false. If year is equal, compare the month. If year is equal and month is greater, return true, if less, return false. And finally, if year and month are equal, we compare the day. If the day is greater, we return true. Everything else has to be false (equal or less than for day).

And that’s it. Let me know if you spot some errors.

You can contact me via:

gritty [at] smallweb [dot] space