3. Dates and Times

Introduction

Finding Today's Date

;;;-----------------------------
;; use GET-DECODED-TIME to fetch the time
(multiple-value-bind
      (second minute hour date month year day-of-week dst-p tz)
    (get-decoded-time)
  year) ; prints out year using standard library

;; alternatively date-calc provides overlapping functionality
(multiple-value-bind (year month day h m s)
    (today-and-now)                     ; imported from date-calc
  year)                                 ; date-calc approach 

;; how to print out current date as "YYYY-MM-DD" (in approved ISO 8601 fashion)
(multiple-value-bind (year month day) 
    (today)                             ;imported from date-calc
  (format t "The current date is ~A-~2,'0d-~2,'0d" year month day))

;; Alternatively, you could use the format-time function from the
;; CyberTiggyr-Time package:
(format-time t "%Y-%m-%d" (get-universal-time))

;; As you can see, format-time operates on epoch time

Converting DMYHMS to Epoch Seconds

;;;-----------------------------
;; to encode time into universal time using date-calc
(multiple-value-bind
      (second minute hour date month year day-of-week dst-p tz)
    (get-decoded-time)
  (encode-universal-time second minute hour date month year))

;; The last two return values for get-decoded-time correspond to
;; daylight savings and the timezone.  Both are useful for
;; timezone-related arithmetic.

;;; @@INCOMPLETE@@
;; An example of a GMT computation with and without daylight savings
;; is appropriate here since the built-in perl functions handle this.

Converting Epoch Seconds to DMYHMS

;;;-----------------------------
(let ((time (get-universal-time))) ; get epoch seconds
  (multiple-value-bind
      (second minute hour day month year day-of-week dst-p tz)
      (decode-universal-time time) ; decode and...
    (list day month year hour minute second))) ; return

Adding to or Subtracting from a Date

;;;-----------------------------

;; when using universal time you add or subtract seconds
;; here we add one hour
(let ((firstdate 
       (encode-universal-time 0 12 6 23 11 2006))
      (onehour (* 60 60 1)))
  (+ onehour firstdate))

;; or you could use date-calc function
;; here we'll add one day
(add-delta-ymdhms 2006 11 24 18 12 0  0 0 1 0 0 0)

Difference of Two Dates

;;;-----------------------------
;; We'll use the epoch seconds to perform subtraction, 
;; then divide by seconds per day
(let ((first (encode-universal-time 52 45 20 13 12 1901))
      (second (encode-universal-time 7 14 3 19 1 2038)))
  (float (/ (- second first) (* 60 60 24))))

;; method two uses delta-days from the date-calc package:
(delta-days 1901 12 13 2038 1 19)

;; delta-days does not yet have the granularity of seconds, minutes or hours. 

Day in a Week/Month/Year or Week Number

;;;-----------------------------
;; The week of the year is computed as follows:
(week-number 2006 12 1)      ; week-of-year is imported from date-calc

;; similar functions exist for day of week, day of year, etc.

Parsing Dates and Times from Strings

;;;-----------------------------
(parse-time "2006-08-20")

;; PARSE-TIME can recognize many of the commonly found date formats

; format-time comes with several ways to format...
(format-time t *format-time-date* (get-universal-time))

; results in: 25 Nov 2006

(format-time t *format-time-iso8601-short* (get-universal-time))

; results in: 20061125T172917 -5

(format-time t "%Y-%m-%d" (get-universal-time))

; results in: 2006-11-25

Printing a Date

High-Resolution Timers

Short Sleeps

Program: hopdelta