3. Dates and Times

Introduction

# Dates and times are handled in PicoLisp by the built-in 'date' and 'time'
# functions, and additional functions like 'day' and 'week', and various
# functions for formatting and localization
#-----------------------------
: (prinl
   "Today is day "
   (- (date) (date (car (date (date))) 1 1) -1)
   " of the current year." )
Today is day 365 of the current year.
#-----------------------------

Finding Today's Date

#-----------------------------
: (date (date))
-> (2010 12 31)
#-----------------------------
: (prinl "The current date is " (dat$ (date) " "))
The current date is 2010 12 31
#-----------------------------
: (prinl "The current date is " (dat$ (date) "-"))
The current date is 2010-12-31
#-----------------------------
: (prinl (stamp))
2010-12-31 13:31:27
#-----------------------------

Converting DMYHMS to Epoch Seconds

#-----------------------------
: (- (+ (* 86400 (date T)) (time T)) (* 86400 (date 1970 1 1)))
-> 1293799342

: (- (+ (* 86400 (date 2010 12 30)) (time 6 57 52)) (* 86400 (date 1970 1 1)))
-> 1293692272

: (- (+ (* 86400 ($dat "20101230")) ($tim "6:57:52")) (* 86400 (date 1970 1 1)))
-> 1293692272
#-----------------------------

Converting Epoch Seconds to DMYHMS

#-----------------------------
: (let
   (Secs (+ 1293692272 (* 86400 (date 1970 1 1)))
      Date (/ Secs 86400)
      Time (% Secs 86400) )
   (prinl "Date: " (datSym Date) ",  time: " (tim$ Time T)) )
Date: 30dec10,  time: 06:57:52
#-----------------------------

Adding to or Subtracting from a Date

# See also the add/subtract in above epoch calculations
#-----------------------------
: (let D (date)
   (prinl
      "Today: " (day D) ", " (datStr D)
      " -> next week: " (day (inc 'D 7)) ", " (datStr D) ) )
Today: Friday, 2010-12-31 -> next week: Friday, 2011-01-07
#-----------------------------

Difference of Two Dates

#-----------------------------
: (prinl
   "Today Jimi Hendrix would be "
   (- (date) (date 1942 11 27))
   " days old" )
Today Jimi Hendrix would be 24871 days old
#-----------------------------

Day in a Week/Month/Year or Week Number

#-----------------------------
: (prinl "Today is " (day (date)))
Today is Friday

: (prinl "Jimi Hendrix was born on a " (day (date 1942 11 27)))
Jimi Hendrix was born on a Friday
#-----------------------------
: (prinl "This is the " (week (date)) "th week")
This is the 52th week
#-----------------------------
: (prinl "This is the " (cadr (date (date))) "th month")
This is the 12th month
#-----------------------------
: (prinl "This is the year " (car (date (date))))
This is the year 2010
#-----------------------------

Parsing Dates and Times from Strings

#-----------------------------
# Calculate the days since the epoch
: (- (date) ($dat "1998-06-03" "-"))
-> 4594
#-----------------------------
: (date (expDat "31"))
-> (2010 12 31)

: (date (expDat "3112"))
-> (2010 12 31)

: (date (expDat "311210"))
-> (2010 12 31)

: (date (expDat "31.12.10"))
-> (2010 12 31)

: (date (expDat "31.12"))
-> (2010 12 31)
#-----------------------------

Printing a Date

#-----------------------------
(load "@lib/http.l")

: (httpDate (date T) (time T))
Fri, 31 Dec 2010 13:21:03 GMT
#-----------------------------
: (stamp)
-> "2010-12-31 14:21:47"
#-----------------------------
: (datStr (date))
-> "2010-12-31"

: (locale "DE" "de")

: (datStr (date))
-> "31.12.2010"

: (locale "JP" "jp")

: (datStr (date))
-> "2010/12/31"
#-----------------------------

High-Resolution Timers

#-----------------------------
: (usec)         # Microseconds
-> 250502252
#-----------------------------
: (let U (usec)
   (prin "Press return when ready: ")
   (line)
   (prinl "You took " (format (- (usec) U) 6) " seconds") )
Press return when ready:
You took 2.711455 seconds
#-----------------------------
: (bench (prin "Press return when ready: ") (line))
Press return when ready:
1.332 sec
#-----------------------------
# Generate, sort and count 1 million random numbers
: (bench (length (sort (make (do 1000000 (link (rand)))))))
2.839 sec
-> 1000000
#-----------------------------

Short Sleeps

#-----------------------------
(wait 250)  # Sleep 0.25 secs
#-----------------------------
: (key 4000)  # Wait max. 4 secs for a keypress
-> "a"        # (pressed "a" after 2 seconds)

: (key 4000)
-> NIL        # (timed out)
#-----------------------------

Program: hopdelta

#-----------------------------
# download the following standalone program
#!/usr/bin/picolisp /usr/lib/picolisp/lib.l

(load "@lib/misc.l")

(in NIL
   (let (Fmt (-21 -21 -9 -10 10)  Sender "Start"  LastSecs NIL)
      (tab Fmt "Sender" "Recipient" "Time" NIL "Delta")
      (tab Fmt "------" "---------" "----" NIL "-----")
      (for Lst
         (flip
            (make
               (while (from "^JReceived: from ")
                  (let Recipient (till " ^J" T)
                     (from "; ")
                     (from ",")
                     (let
                        (Day (read)
                           Mon (index (till " " T) *Mon)
                           Year (read)
                           Tim (till " " T)
                           Offs (read)
                           Secs (+ (* 86400 (date Year Mon Day)) ($tim Tim)) )
                        (when (num? Offs)
                           (inc 'Secs (*/ 3600 Offs 100)) )
                        (link
                           (list
                              Recipient
                              Tim
                              (dat$ (date Year Mon Day) "/")
                              Secs ) ) ) ) ) ) )
         #(println (list Day Mon Year Tim '- Secs))
         (tab Fmt
            Sender
            (car Lst)
            (cadr Lst)
            (caddr Lst)
            (tim$ (- (cadddr Lst) LastSecs) T) )
         (setq Sender (car Lst)  LastSecs (cadddr Lst)) ) ) )

(bye)

#-----------------------------
$ ./hopdelta <header
Sender               Recipient            Time                    Delta
------               ---------            ----                    -----
Start                app                  15:44:34 2010/12/31
app                  mo-p00-ob.rzone.de   15:44:34 2010/12/31  00:00:00
mo-p00-ob.rzone.de   post.strato.de       15:44:39 2010/12/31  00:00:05
post.strato.de       localhost            15:46:09 2010/12/31  00:01:30
#-----------------------------