Time Formatting Parsing in Lisp

In Lisp, we can format and parse time using various built-in functions and libraries. Here’s an example of how to work with time formatting and parsing:

(defun main ()
  (let ((p #'print))
    ;; Here's a basic example of formatting the current time
    ;; according to ISO 8601 format
    (let ((t (get-universal-time)))
      (funcall p (format-timestring nil (universal-to-timestamp t)
                                    :format :iso8601)))

    ;; Time parsing uses similar format specifiers
    (let ((t1 (parse-timestring "2012-11-01T22:08:41+00:00")))
      (funcall p t1))

    ;; We can use custom format strings for formatting
    (let ((t (get-universal-time)))
      (funcall p (format-timestring nil (universal-to-timestamp t)
                                    :format '(:hour12 ":" :min)))
      (funcall p (format-timestring nil (universal-to-timestamp t)
                                    :format '(:day-of-week " " :mon " " :d " " :hour ":" :min ":" :sec " " :year)))
      (funcall p (format-timestring nil (universal-to-timestamp t)
                                    :format :iso8601-precise)))

    ;; Parsing custom time formats
    (let ((form "~2,'0d ~2,'0d ~a")
          (time-string "08 41 PM"))
      (multiple-value-bind (second minute hour)
          (parse-integer time-string :start 0 :end 2)
        (declare (ignore second))
        (let ((t2 (encode-universal-time 0 minute (if (string= "PM" (subseq time-string 6)) (+ hour 12) hour) 1 1 2000 0)))
          (funcall p (universal-to-timestamp t2)))))

    ;; For purely numeric representations, we can use format directly
    (let ((t (get-universal-time)))
      (format t "~d-~2,'0d-~2,'0dT~2,'0d:~2,'0d:~2,'0d-00:00~%"
              (nth-value 5 (decode-universal-time t))
              (nth-value 4 (decode-universal-time t))
              (nth-value 3 (decode-universal-time t))
              (nth-value 2 (decode-universal-time t))
              (nth-value 1 (decode-universal-time t))
              (nth-value 0 (decode-universal-time t))))

    ;; Parse will signal an error on malformed input
    (handler-case
        (parse-timestring "8:41PM")
      (error (c)
        (funcall p c)))))

(main)

In this Lisp example, we’re using the local-time library for time manipulation, which provides similar functionality to Go’s time package. Here’s a breakdown of the code:

  1. We define a main function to encapsulate our code.

  2. We use get-universal-time to get the current time, similar to time.Now() in Go.

  3. For formatting, we use format-timestring with various format specifiers. The :iso8601 format is similar to RFC3339 in Go.

  4. For parsing, we use parse-timestring which can handle ISO 8601 formatted strings.

  5. We demonstrate custom formatting using format specifiers like :hour12, :min, etc.

  6. For parsing custom formats, we need to do some manual string manipulation and use encode-universal-time.

  7. We show how to format time using purely numeric representations with format.

  8. Error handling for parsing is done using handler-case, which is similar to try-catch in other languages.

Note that Lisp’s time handling is a bit more verbose than Go’s, but it offers similar flexibility. The exact output will depend on the current time when you run the script, but it will follow the same format as the Go example.