r8580: add tests/improvements to ensure-keyword-*
[kmrcl.git] / datetime.lisp
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          datetime.lisp
6 ;;;; Purpose:       Date & Time functions for KMRCL package
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Apr 2000
9 ;;;;
10 ;;;; $Id$
11 ;;;;
12 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;;
14 ;;;; KMRCL users are granted the rights to distribute and use this software
15 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
16 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
17 ;;;; *************************************************************************
18
19 (in-package #:kmrcl)
20
21
22 ;;; Formatting functions
23
24 (defun pretty-date (year month day &optional (hour 12) (m 0) (s 0))
25   (multiple-value-bind (sec min hr dy mn yr wkday)
26     (decode-universal-time
27      (encode-universal-time s m hour day month year))
28     (values (elt '("Monday" "Tuesday" "Wednesday" "Thursday"
29                    "Friday" "Saturday" "Sunday")
30                  wkday)
31             (elt '("January" "February" "March" "April" "May" "June"
32                    "July" "August" "September" "October" "November"
33                    "December")
34                  (1- mn))
35             (format nil "~A" dy) (format nil "~A" yr)
36             (format nil "~2,'0D:~2,'0D:~2,'0D" hr min sec))))
37
38
39 (defun date-string (ut)
40   (if (typep ut 'integer)
41       (multiple-value-bind (sec min hr day mon year dow daylight-p zone)
42           (decode-universal-time ut)
43         (declare (ignore daylight-p zone))
44         (format nil "~[Mon~;Tue~;Wed~;Thu~;Fri~;Sat~;Sun~], ~d ~[Jan~;Feb~;Mar~;Apr~;May~;Jun~;Jul~;Aug~;Sep~;Oct~;Nov~;Dec~] ~d ~2,'0d:~2,'0d:~2,'0d" 
45                 dow
46                 day
47                 (1- mon)
48                 year
49                 hr min sec))))
50
51 (defun print-seconds (secs)
52   (print-float-units secs "sec"))
53
54 (defun print-float-units (val unit)
55   (cond
56     ((< val 1d-6)
57      (format t "~,2,9F nano~A" val unit))
58     ((< val 1d-3)
59      (format t "~,2,6F micro~A" val unit))
60     ((< val 1)
61      (format t "~,2,3F milli~A" val unit))
62     ((> val 1d9)
63      (format t "~,2,-9F giga~A" val unit))
64     ((> val 1d6)
65      (format t "~,2,-6F mega~A" val unit))
66     ((> val 1d3)
67      (format t "~,2,-3F kilo~A" val unit))
68     (t
69      (format t "~,2F ~A" val unit))))
70
71 (defconstant +posix-epoch+
72   (encode-universal-time 0 0 0 1 1 1970 0))
73
74 (defun posix-time-to-utime (time)
75   (+ time +posix-epoch+))
76
77 ;;;; Daylight Saving Time calculations 
78
79 ;; Daylight Saving Time begins for most of the United States at 2
80 ;; a.m. on the first Sunday of April. Time reverts to standard time at
81 ;; 2 a.m. on the last Sunday of October. In the U.S., each time zone
82 ;; switches at a different time.
83
84 ;; In the European Union, Summer Time begins and ends at 1 am
85 ;; Universal Time (Greenwich Mean Time). It starts the last Sunday in
86 ;; March, and ends the last Sunday in October. In the EU, all time
87 ;; zones change at the same moment.
88
89 ;; Spring forward, Fall back
90 ;; During DST, clocks are turned forward an hour, effectively moving
91 ;; an hour of daylight from the morning to the evening.
92
93 ;; United States                  European Union
94
95 ;; Year  DST Begins DST Ends     Summertime     Summertime
96 ;;       at 2 a.m.  at 2 a.m.    period begins  period ends
97 ;;                               at 1 a.m. UT   at 1 a.m. UT
98 ;; ----------------------------------------------------------
99 ;; 2000  April 2   October 29    March 26       October 29
100 ;; 2001  April 1   October 28    March 25       October 28
101 ;; 2002  April 7   October 27    March 31       October 27
102 ;; 2003  April 6   October 26    March 30       October 26
103 ;; 2004  April 4   October 31    March 28       October 31
104 ;; 2005  April 3   October 30    March 27       October 30
105 ;; 2006  April 2   October 29    March 26       October 29
106 ;; 2007  April 1   October 28    March 25       October 28
107 ;; 2008  April 6   October 26    March 30       October 26
108
109