PLEAC examples - 3. Dates and Times

3.0. 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.

3.1. Find todays date and display it in several forms

You need to find the year, month, and day values for today's date.

3.1.1. Example

   : (date)
   -> 737156

   : (date (date))
   -> (2018 6 5)

   : (prinl "The current date is " (dat$ (date) " "))
   The current date is 2018 06 05
   -> "2018 06 05"

   : (prinl "The current date is " (dat$ (date) "-"))
   The current date is 2018-06-05
   -> "2018-06-05"

   : (prinl (stamp))
   2018-06-05 12:34:02
   -> "2018-06-05 12:34:02"
References date dat$ prinl stamp

3.1.2. Find the day number of the current date

   : (prinl
      "Today is day "
      (- (date) (date (car (date (date))) 1 1) -1)
      " of the current year." )
   Today is day 156 of the current year.
   -> " of the current year."
References - car date prinl

3.2. Convert date and time to Epoch Seconds and vice versa

You want to convert a date, a time, or both with distinct values for day, month, year, etc. to Epoch seconds.

PicoLisp uses the Linux System Date, which is based on the number of seconds since 01 Jan 1970 at 12AM UTC (Coördinated Universal Time).

3.2.1. Convert date and time to Epoch Seconds

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

   : (- (+ (* 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
References - + * $dat date $tim time

3.3. Convert Epoch Seconds to a date and time

You have a date and time in Epoch seconds, and you want to calculate individual DMYHMS values from it.

3.3.1. Example

   : (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
   -> "06:57:52"
References + * % date datsym let prinl tim$

3.4. Adding to or Subtracting from a Date

You have a date and time and want to find the date and time of some period in the future or past.

3.4.1. Example

   : (let D (date)
       (prinl
         "Today: " (day D) ", " (datStr D)
         " -> next week: " (day (inc 'D 7)) ", " (datStr D) ) )
   Today: Tuesday, 2018-06-05 -> next week: Tuesday, 2018-06-12
   -> "2018-06-12"
References date datstr day inc let prinl

3.5. Difference of two Dates

You have a date and time and want to find the date and time of some period in the future or past.

3.4.1. Example

   : (prinl
      "Today Jimi Hendrix would be "
      (- (date) (date 1942 11 27))
      " days old" )
   Today Jimi Hendrix would be 27584 days old
   -> " days old"
References - date prinl

3.6. Day in a Week/Month/Year or Week Number

You have a date, either in Epoch seconds or as distinct year, month, etc. values.

You want to find out what week of the year, day of the week, day of the month, or day of the year that the date falls on.

3.6.1. Example

   # Day in the week
   : (prinl "Today is " (day (date)))
   Today is Tuesday
   -> "Tuesday"

   # Name of day at a specific date
   : (prinl "Jimi Hendrix was born on a " (day (date 1942 11 27)))
   Jimi Hendrix was born on a Friday
   -> "Friday"

   # Week number in current year
   : (prinl "This is the " (week (date)) "th week")
   This is the 23th week
   -> "th week"

   # Month number in current year
   : (prinl "This is the " (cadr (date (date))) "th month")
   This is the 6th month
   -> "th month"

   # Current year number
   : (prinl "This is the year " (car (date (date))))
   This is the year 2018
   -> 2018
References car cadr date day prinl week

3.7. Parsing Dates and Times from Strings

You read in a date or time specification in an arbitrary format but need to convert that string into distinct year, month, etc. values.

3.7.1. Example

   # Number of days since start of the century
   : (- (date) ($dat "2000-01-01" "-"))
   -> 6730

   # Note: pitfall ahead!
   # Since the function 'expDat' tries to show the date consisting of:
   #    - current year
   #    - current month
   #    - the day given (here 28)
   # it will return NIL if that day does not exist for that month
   # and if february also concerning leap years!

   : (date (expDat "28"))
   -> (2018 6 28)

   : (date (expDat "2806"))
   -> (2018 6 28)

   : (date (expDat "280618"))
   -> (2018 6 28)

   : (date (expDat "28.06.18"))
   -> (2018 6 28)

   : (date (expDat "28.06"))
   -> (2018 6 28)
References - $dat date expDat

3.8. Printing a Date

You need to print a date and time shown in Epoch seconds format in human-readable form.

3.8.1. Example

   # Get date and time from the internet
   : (load "@lib/http.l")
   -> http404

   : (httpDate (date T) (time T))
   Tue, 05 Jun 2018 11:26:36 GMT
   -> " GMT^M"

   # Time stamp
   : (stamp)
   -> "2018-06-05 13:26:48"

   # Influence the way a date is shown, depending on a coutries locale

   # Dutch (NL) locale
   : (datStr (date))
   -> "2018-06-05"

   # German locale
   : (locale "DE" "de")
   -> "männlich"

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

   # Japanese locale
   : (locale "JP" "jp")
   -> "男性"

   : (datStr (date))
   -> "2018/06/05"
Reference to 'httpDate' will be added later.

References date datstr load locale ^(https://software-lab.de/doc/refS.html#stamp stamp} time

3.9. High-Resolution Timers

You need to measure time with a finer granularity than the full seconds that time returns.

3.9.1. Example

   : (usec)
   -> 232870367   # microseconds since start PicoLisp or calling 'time'

   # Check your response time ...
   : (let U (usec)
        (prin "Press return when ready: ")
        (line)
        (prinl "You took " (format (- (usec) U) 6) " seconds") )
   Press return when ready:
   You took 0.976134 seconds
   -> " seconds"

   # Benchmark how long it takes to type a line of text ...
   : (bench (prin "Press return when ready: ") (line))
   Press return when ready: abcdefg
   3.472 sec
   -> ("a" "b" "c" "d" "e" "f" "g")

   # Generate, sort and count 1 million random numbers
   : (bench (length (sort (make (do 1000000 (link (rand)))))))
   0.799 sec
   -> 1000000
References - bench do format length let line link make prin prinl rand sort usec

3.10. Short Sleeps

You need to sleep for less than a second.

3.10.1. Example

   # Wait 250 milliseconds
   : (wait 250)
   -> NIL

   # Use 'key' to wait for a key press for at most n milliseconds
   : (key 4000)
   -> "r"          # 'r' key pressed before time-out

   : (key 4000)
   -> NIL          # time-out before a key was pressed
References key wait

https://picolisp.com/wiki/?pcepleacdatetime

23jun18    ArievW