Erwin Vrolijk
Erwin Vrolijk

Reputation: 363

Lisp: decode-universal-time is void

I'm editing orgmode, a time-management mode for emacs. I'm adding some new time functions. In my addition i need to determine the day of the week for a given date. I use the following code:

(defun org-day-of-week (day month year)
(nth-value 6 (decode-universal-time (encode-universal-time 0 0 0 day month year 0) 0)))

Executing this code gives me the error:

nth-value: Symbol's function definition is void: decode-universal-time

I'm new to lisp, and can't find any info related to this error. I presume some libraries aren't loaded or available. Can anyone please shed a light on this?

Regards, Erwin Vrolijk Snow.nl

Upvotes: 1

Views: 438

Answers (3)

Trey Jackson
Trey Jackson

Reputation: 74480

A cleaner version of Vatine's answer is:

(defun day-of-week (year month day)
  "Return the day of the week given a YEAR MONTH DAY"
  (nth 6 (decode-time (encode-time 0 0 0 day month year))))

decode-time and encode-time are documented here.

Upvotes: 2

Erwin Vrolijk
Erwin Vrolijk

Reputation: 363

I haven't found the source of this problem, but found a workaround:

(defun day-of-week (day month year)
  "Returns the day of the week as an integer.
Sunday is 0. Works for years after 1752."
  (let ((offset '(0 3 2 5 0 3 5 1 4 6 2 4)))
    (when (< month 3)
      (decf year 1))
    (mod
     (truncate (+ year
                  (/ year 4)
                  (/ (- year)
                     100)
                  (/ year 400)
                  (nth (1- month) offset)
                  day
                  -1))
     7)))

Upvotes: -1

Vatine
Vatine

Reputation: 21288

Essentially decode-universal-time is a Common Lisp function. These are not necessarily available in emacs-lisp. Some quick checking in a local emacs indicates that this is the fact.

Something close to your original implementation would be:

(defun org-day-of-week (year month day)
   (nth 6 
        (decode-time 
           (date-to-time 
             (format "%d-%02d-%02dT00:00:00" year month day)))))

You should be able to use decode-time instead (maybe in conjuction with date-to-time):

decode-time is a built-in function in `C source code'. (decode-time &optional specified-time) Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST ZONE). The optional specified-time should be a list of (HIGH LOW . IGNORED), as from `current-time' and `file-attributes', or nil to use the current time. The obsolete form (HIGH . LOW) is also still accepted. The list has the following nine members: SEC is an integer between 0 and 60; SEC is 60 for a leap second, which only some operating systems support. MINUTE is an integer between 0 and 59. HOUR is an integer between 0 and 23. DAY is an integer between 1 and 31. MONTH is an integer between 1 and 12. YEAR is an integer indicating the four-digit year. DOW is the day of week, an integer between 0 and 6, where 0 is Sunday. DST is t if daylight saving time is in effect, otherwise nil. ZONE is an integer indicating the number of seconds east of Greenwich. (Note that Common Lisp has different meanings for DOW and ZONE.)

Upvotes: 3

Related Questions