(Note I am talking about my 1common-lisp/0time-iterator.lisp)
On the off chance that it is directly useful, I wrote 40 somewhat daunting
lines of code that directly do roughly what I think C was describing.
Aside from the program being useful, my thinking is to provide a
counterpoint to most date programming online examples. Common lisp in
particular and programming in general sometimes has unreliable commentary by
non-lispers (sez me). I will try to be complete here (more than I think many
people might need).
I installed a lisp compiler, ecl, like this as root:
```openbsd
pkg_add ecl
```
Or on some linuxes:
```gentoo
emerge ecls
```
(I don't know why that s is there)
```debian
apt-get install -y ecl
```
and download my lisp code, time-iterator.lisp. The code has several notes
where number values might like to be changed.
One way of running time-iterator.lisp is like this:
```ksh
ecl --load time-iterator.lisp
```
$ ecl --load time-iterator.lisp
;;; Loading "/path/of/time-iterator.lisp"
date:29 month:12 year:1969
date:1 month:1 year:1970
date:4 month:1 year:1970
date:28 month:1 year:1970
date:31 month:1 year:1970
date:3 month:2 year:1970
date:27 month:2 year:1970
date:2 month:3 year:1970
date:5 month:3 year:1970
date:29 month:3 year:1970
date:1 month:4 year:1970
date:4 month:4 year:1970
date:28 month:4 year:1970
date:1 month:5 year:1970
date:4 month:5 year:1970
$
```
Portability:
At the end of the program I use the ecl compiler's si:quit. In sbcl that
would be sb-ext:quit.
Mechanism:
I (defvar variablename) some variables, or (defparameter parametername) when
value will not be changeable.
Then I (setq variablename new-value) inside a 'let. It's like this (but this
is not useful/from the program)
(defvar *foo*)
(let ((a 3) (b 4))
(setq *foo* (* a b)))
(princ *foo*)
> 12
Let provides locally scoped variables.
In lisp normally everything you write is a list like this:
(function argument argument)
So we know by position in the list that in
(* a b)
#'* is a function and a and b its arguments. Similarly,
(setq *foo* (* a b))
Has the special function #'setq, with the arguements *foo* and (* a b).
Innermost lists are evaluated first.
The loop facility:
I just used #'loop to do almost everything. Loops are kind of like this:
> (loop for x from 1 to 10 by 2 do (princ x) do (terpri) finally (terpri))
1
3
5
7
9
NIL
>
Any whitespace in lisp, including newlines is treated the same. (terpri)
sends a newline to the terminal. Another way to do that loop would be:
> (loop for x in (list 1 3 5 7 9) do (princ x) do (terpri) finally (terpri))
In general there can be lots of fors and lots of dos, and it's common to put
additional loops inside a do.
PS:
A different view on time/date programming in lisp that is well known follows
http://cl-cookbook.sourceforge.net/dates_and_times.html
PPS:
I forgot the most important part. C if you look into lisp, I would love to
know more from Japan about Kyoto Common Lisp (the parent of ECL). The copy-
right on the free software license starts at
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
which I guess is why ECL's
> (describe 'get-decoded-time)
includes an explanation that Japan's time zone is -9, and that the year is
Christian and not long-live-Emperor.