|
- ;; I noticed I've been doing a lot of work with time. This is time
- ;; helpers.
-
- (in-package #:cl-deck-builder2.toolkit.time)
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun time-format (when &optional (format local-time:+rfc3339-format+))
- (local-time:format-timestring nil when :format format))
-
- (defun time-format/date-only (when)
- (time-format when local-time:+rfc3339-format/date-only+))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun day- (when &optional (amount 1))
- "Subtract AMOUNT days from WHEN."
- (local-time:timestamp- when amount :day))
-
- (defun day+ (when &optional (amount 1))
- "Add AMOUNT days to WHEN."
- (local-time:timestamp+ when amount :day))
-
- (defun month- (when &optional (amount 1))
- "Subtract AMOUNT months from WHEN."
- (local-time:timestamp-
- (local-time:timestamp- when amount :month)
- local-time:+seconds-per-day+ :sec))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun time-now ()
- "Today's date, passed through FORMAT-DMY."
- (local-time:now))
-
- (defun time-yesterday ()
- "Yesterday's date, passed through FORMAT-DMY."
- (day- (time-now)))
-
- ;; TODO Why am I using this?
- (defun time-first-of-month ()
- "The first day of this month."
- (local-time:timestamp-minimize-part
- (time-now) :day))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun n-month-list (&key (when (time-now)) (start 1) (n 6))
- "Produce a LIST of the last N months, using WHEN as the reference point.
- The values iterate numerically from START, that is, the result will be length N - START.
- The date will be on the first of each month, in chronological order."
- (mapcar (lambda (n)
- (month- when n))
- (loop for i from start upto n collect i)))
-
- (defun n-day-list (&key (when (time-now)) (start 0) (n 5))
- "Produce a LIST of the last N days, using WHEN as a reference point.
- The values will iterate numerically from START, that is, the result will be length N - START.
- The exact times will not be modified. The results will be in chronological order."
- (mapcar (lambda (n)
- (day- when n))
- (loop for i from start upto n collect i)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun time-friday (&key (when (time-now)))
- (local-time:adjust-timestamp
- when
- (offset :day-of-week :friday)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defun format-status-report (&key (stream *standard-output*) (when (time-friday)))
- (let ((date-str (time-format/date-only when))
- (day-map (reverse
- (mapcar #'time-format/date-only (n-day-list :when when :n 4)))))
- (format stream
- "#+TITLE: Status Report: Week of ~A~%~%* Status Report: ~
- Week of ~A~%~%Total hours: 40 h.~%~%~{** ~A~%~%Hours: 0800A-1600P (8h)~%~%~}"
- date-str date-str day-map)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- (defparameter *status-report-base-dir*
- (probe-file #P"~/code/cl-deck-builder2/doc/status-report/"))
-
- (defun generate-status-report (&key (when (time-friday)))
- (let ((filespec (merge-pathnames
- (format nil "~a.org" (time-format/date-only when))
- *status-report-base-dir*)))
- (with-open-file (f filespec
- :direction :output
- :if-exists :error
- :if-does-not-exist :create)
- (format-status-report :stream f :when when)
- (probe-file filespec))))
|