How to decode name of month into an integer - emacs

I'm trying to write a function that will let me choose (interactively) the month and year for org-agenda-month-view -- which uses a format of 201312 (without double-quotes) for December 2013 . I would like to use either words (December) or numbers (12) for the month, but need some assistance (please) to decode the name of the month into an integer -- something like (if (not (integer-p month)) (setq month (decode-name-of-month month))).
Also, any pointers on how to consolidate my two read-string  let bindings into just one action would be greatly appreciated -- i.e., be able to manually input January 2014 or 01 2014; instead of first inputting January and then inputting 2014 in two separate actions.
(let* (
(year (read-string "Insert the year: "))
(month (read-string "Insert the month: ")))
(org-agenda nil "1")
(org-agenda-month-view (read (format "%s%02s" year month))))
EDIT (December 11, 2013):  First working draft based upon the helpful answers by #Drew and #Sean Perry. Added variable org-agenda-start-day, which permits (org-agenda nil "1") to display [at the outset] the correct month based upon the user input -- the function org-agenda-month-view is no longer needed. Updated variable lawlist-parse-time-months to fix a typo and include additional possibilities -- e.g., 01, 02, etc.
(defvar lawlist-parse-time-months '(
("1" . "01")
("01" . "01")
("jan" . "01")
("january" . "01")
("2" . "02")
("02" . "02")
("feb" . "02")
("february". "02")
("3" . "03")
("03" . "03")
("mar" . "03")
("march" . "03")
("4" . "04")
("04" . "04")
("apr" . "04")
("april" . "04")
("5" . "05")
("05" . "05")
("may" . "05")
("6" . "06")
("06" . "06")
("jun" . "06")
("june" . "06")
("7" . "07")
("07" . "07")
("jul" . "07")
("july" . "07")
("8" . "08")
("08" . "08")
("aug" . "08")
("august" . "08")
("9" . "09")
("09" . "09")
("sep" . "09")
("september" . "09")
("10" . "10")
("oct" . "10")
("october" . "10")
("11" . "11")
("nov" . "11")
("november" . "11")
("12" . "12")
("dec" . "12")
("december" . "12")))
(defun encode-name-of-month (month_name)
(cdr (assoc (downcase month_name) lawlist-parse-time-months)) )
(defun decode-name-of-month (month)
(car (rassoc month lawlist-parse-time-months)))
(defun foo (month year)
(interactive
(let* ((mon+yr (split-string
(read-string "Month and year: " nil nil
(format-time-string "%B %Y"(current-time)))
nil 'TRIM))
(mon (car mon+yr))
(yr (cadr mon+yr))
(m2 (condition-case nil (format "%d" mon) (error nil))))
(list (or m2 mon) yr)))
(setq org-agenda-start-day (concat year "-" (encode-name-of-month month) "-" "01"))
(org-agenda nil "1") )

(require 'parse-time) ;; in standard lib
(defun encode-name-of-month (month_name)
(cdr (assoc (downcase month_name) parse-time-months))
)
(defun decode-name-of-month (month)
(car (rassoc month parse-time-months))
)
That should get you started.

(defun foo (month year)
(interactive
(let* ((mon+yr (split-string
(read-string "Month and year: " nil nil
(format-time-string "%B %Y"(current-time)))
nil 'TRIM))
(mon (car mon+yr))
(yr (cadr mon+yr))
(m2 (condition-case nil (format "%d" mon) (error nil))))
(list (or m2 mon) yr)))
(message "Month: %s, Year: %s" month year))
M-x foo 12 2013 ==> Month: 12, Year: 2013
M-x foo December 2013 ==> Month: December, Year: 2013
M-x foo Dec 2013 ==> Month: Dec, Year: 2013
M-x foo Nebraska 200000 ==> Month: Nebraska, Year: 200000
But you get the idea. (Check for valid month names and month & year numbers.)

Related

How to compute number of days between the entered years

How can I get the number of days between the given years, should I use loops?
Here's what I have now
(princ "Enter starting year: ")
(defparameter w (read))
(princ "Enter ending year: ")
(defparameter x (read))
(defun print-list (w x)
(format t "Starting year: ~a ~%" (list w))
(format t "Ending year: ~a ~%" (list x)))
(terpri)
(if(> x w)
(format t "Number of year/s: ~a ~%"(- x w))
(format t "Number of year/s: ~a ~%"(- w x)))
I'm trying to compute the days between years but the output was always failed.
A simple set of functions to perform the calculation is the following:
(defun leap-year-p (year)
"return t if year is a leap-year, nil otherwise"
(or (and (zerop (mod year 4))
(not (zerop (mod year 100))))
(zerop (mod year 400))))
(defun days-of (year)
"return the number of days of a certain year"
(if (leap-year-p year) 365 366))
(defun days-between (start-year end-year)
"return the number of days between start-year (included)
and end-year (excluded)"
(when (<= start-year end-year)
(loop for year from start-year below end-year sum (days-of year)))
A few examples of call:
CL-USER> (days-between 2020 2022)
731
CL-USER> (days-between 1820 1999)
65470
CL-USER> (days-between 2020 2020)
0
CL-USER> (days-between 1980 1890)
NIL
You can use these function to solve your problem.

Return date and time in another format autocad

I have a little problem with my code. I want to disply the time and date in format from autocad is displayed. For example tdcreate command in autocad show 2458753.59648148 but this code show in the output file 26 September 2019 14:18:55:999. I don't know where is wrong. I want to appear 2458753.59648148 .
(progn
(foreach item
'(
("Current time:" "DATE" "DD MONTH YYYY HH:MM:SS:MSEC")
("Created:" "TDCREATE" "DD MONTH YYYY HH:MM:SS:MSEC")
("Last updated:" "TDUPDATE" "DD MONTH YYYY HH:MM:SS:MSEC")
("Total editing time:" "TDINDWG" "HH:MM:SS:MSEC")
("Elapsed timer:" "TDUSRTIMER" "HH:MM:SS:MSEC")
)
(write-line
(strcat
(PadRight (car item) " " 24)
(apply 'FormatDate (cdr item))
)
openfile
)
)
(close openfile)
(startapp "notepad" filename)
)
(princ (strcat "\nUnable to Write to " filename))
)
(princ)
)
(defun PadRight ( string char lengtth )
(if (< (strlen string) lengtth)
(PadRight (strcat string char) char lengtth)
string
)
)
(defun GetUniqueFilename ( seed / count file flist )
(if (findfile (setq file seed))
(progn
(setq count 1
flist (fnsplitl seed)
)
(while
(findfile
(setq file
(strcat
(car flist)
(cadr flist)
"(" (itoa (setq count (1+ count))) ")"
(caddr flist)
)
)
)
)
)
)
file
)
(defun FormatDate ( sysvar format )
(menucmd (strcat "m=$(edtime,$(getvar," sysvar ")," format ")"))
)
In AutoCAD, the TDCREATE command is merely returning the value held by the TDCREATE system variable, which stores the Julian datetime value of when the drawing was created.
The code that you have posted from my program is formatting this Julian datetime value using the DIESEL edtime function within a menu command expression.
If you want the raw Julian value, you can simply use:
(getvar 'tdcreate)
Which could be formatted as a string using rtos, i.e.:
(rtos (getvar 'tdcreate) 2 16)

matcher association list lisp

Hi everyone I am new to programming and I have to work with association list like this
((course (john .math) (jim .english) (carl .biology) )
(year (john .2) (jim. 1) (carl .3))
(age (john .22) (jim .20) (carl .27))
)
I am supposed to use the matcher to work like that with a function lookup
(lookup 'john 'course data) and return math
Now I am new to programming and completely new to Lisp and need to do this for the school. Now I do not need a complete solution necessary but some ideas or instructions.
This is what I have though so far but took me a lot of time
If someone can help it will be much appreciated!!!!
(defun lookup (name course data)
(matches '(name course data) '(first course ))
)
First let's put the data into a list called data. Pay attention that the list needs to be quoted by ', and that the . dot signs need to be surrounded by spaces because they have a signification of their own:
(defparameter *data* '((course (john . math) (jim . english) (carl . biology))
(year (john . 2) (jim . 1) (carl . 3))
(age (john . 22) (jim . 20) (carl . 27))))
Now let's try using procedure assoc:
? *data*
((COURSE (JOHN . MATH) (JIM . ENGLISH) (CARL . BIOLOGY)) (YEAR (JOHN . 2) (JIM . 1) (CARL . 3)) (AGE (JOHN . 22) (JIM . 20) (CARL . 27)))
? (assoc 'course *data*)
(COURSE (JOHN . MATH) (JIM . ENGLISH) (CARL . BIOLOGY))
? (cdr (assoc 'course *data*))
((JOHN . MATH) (JIM . ENGLISH) (CARL . BIOLOGY))
? (assoc 'john (cdr (assoc 'course *data*)))
(JOHN . MATH)
? (cdr (assoc 'john (cdr (assoc 'course *data*))))
MATH
so the function becomes
(defun lookup (name attr data)
(cdr (assoc name (cdr (assoc attr data)))))
(lookup 'john 'course *data*)
=> MATH
(lookup 'carl 'age *data*)
=> 27

How to convert (day month year) to ( month day year)

My e-mails in Wanderlust have a header that looks like this:
Date: Wed, 23 Oct 2013 12:18:15 -0700
I would like to modify the beginning of my print-to-pdf function so that it searches the current buffer for the first date it finds (usually the first line of the buffer) and converts it into a proposed pdf-file-name that looks like this:
10_23_2013.pdf
The beginning of my print-to-pdf function looks like this:
(defun print-to-pdf (pdf-file-name)
"Print the current buffer to the given file."
(interactive (list
(ns-read-file-name "Write PDF file: " "/Users/HOME/.0.data/" nil ".pdf")))
(cond (
(not (equal pdf-file-name nil))
***
Can anyone think of a way to search for the date and turn it into a proposed pdf-file-name?
EDIT:  Here are some of the date string functions I found by grepping the Wanderlust code:
(defun wl-make-date-string ()
(let ((system-time-locale "C"))
(format-time-string "%a, %d %b %Y %T %z")))
(defsubst wl-get-date-iso8601 (date)
(or (get-text-property 0 'wl-date date)
(let* ((d1 (timezone-fix-time date nil nil))
(time (format "%04d%02d%02dT%02d%02d%02d"
(aref d1 0) (aref d1 1) (aref d1 2)
(aref d1 3) (aref d1 4) (aref d1 5))))
(put-text-property 0 1 'wl-date time date)
time)))
(defun wl-make-date-string ()
(let ((s (current-time-string)))
(string-match "\\`\\([A-Z][a-z][a-z]\\) +[A-Z][a-z][a-z] +[0-9][0-9]? *[0-9][0-9]?:[0-9][0-9]:[0-9][0-9] *[0-9]?[0-9]?[0-9][0-9]"
s)
(concat (wl-match-string 1 s) ", "
(timezone-make-date-arpa-standard s (current-time-zone)))))
(defun wl-date-iso8601 (date)
"Convert the DATE to YYMMDDTHHMMSS."
(condition-case ()
(wl-get-date-iso8601 date)
(error "")))
Here's the function.
If you can find a way to extract Wed, 23 Oct 2013 12:18:15 -0700, it will produce
10_23_2013.pdf.
(defun transform-date (s &optional shift)
(let ((time (apply 'encode-time
(org-read-date-analyze
s nil
(decode-time (current-time))))))
(when shift
(setq time (time-add time (days-to-time shift))))
(format-time-string "%m_%d_%Y.pdf" time)))
Here's a simple finder for the date:
(defun find-and-transform ()
(goto-char (point-min))
(when (re-search-forward "Date: \\([^:]*?\\)[0-9]+:")
(transform-date
(match-string-no-properties 1))))

Custom function for next / previous month in agenda view and the calendar

I'm looking for a way to select next or previous month in both agenda view and the calendar. I've written a concept/prototype function (below), but it doesn't calculate the next or previous months and I would also need to rewrite the function every month.
The date format for the org-agenda-month-view is different than the date format for calendar-other-month. Further down below are some functions that are related to what I'm trying to accomplish -- e.g., calendar already has the ability to move forward or backward by month.
I think what may be needed is a function that identifies the month being viewed and then adds plus-or-minus one month (in the proper format) when hitting the next or previous button.
(defun lawlist-org-agenda-view-mode-dispatch ()
"Select the month in agenda view."
(interactive)
(message "View: [7] JUL | [8] AUG | [9] SEP | [o]CT | [n]OV | [d]EC ")
(let ((a (read-char-exclusive)))
(case a
(?7
(org-agenda nil "a")
(org-agenda-month-view 201307)
(calendar)
(calendar-other-month 7 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?8
(org-agenda nil "a")
(org-agenda-month-view 201308)
(calendar)
(calendar-other-month 8 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?9
(org-agenda nil "a")
(org-agenda-month-view 201309)
(calendar)
(calendar-other-month 9 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?o
(org-agenda nil "a")
(org-agenda-month-view 201310)
(calendar)
(calendar-other-month 10 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?n
(org-agenda nil "a")
        (org-agenda-month-view 201311)
(calendar)
(calendar-other-month 11 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?d
(org-agenda nil "a")
(org-agenda-month-view 201312)
(calendar)
(calendar-other-month 12 2013)
(lawlist-org-agenda-view-mode-dispatch))
(?q (message "Abort"))
(otherwise (error "Either press \"q\" to quit, or select another option." )))))
Here are some related functions I've extracted from cal-move.el and calendar.el:
(defun calendar-other-month (month year &optional event)
"Display a three-month calendar centered around MONTH and YEAR.
EVENT is an event like `last-nonmenu-event'."
(interactive (let ((event (list last-nonmenu-event)))
(append (calendar-read-date 'noday) event)))
(save-selected-window
(and event
(setq event (event-start event))
(select-window (posn-window event)))
(unless (and (= month displayed-month)
(= year displayed-year))
(let ((old-date (calendar-cursor-to-date))
(today (calendar-current-date)))
(calendar-generate-window month year)
(calendar-cursor-to-visible-date
(cond
((calendar-date-is-visible-p old-date) old-date)
((calendar-date-is-visible-p today) today)
(t (list month 1 year))))))))
;;;###cal-autoload
(defun calendar-forward-month (arg)
"Move the cursor forward ARG months.
Movement is backward if ARG is negative."
(interactive "p")
(calendar-cursor-to-nearest-date)
(let* ((cursor-date (calendar-cursor-to-date t))
(month (calendar-extract-month cursor-date))
(day (calendar-extract-day cursor-date))
(year (calendar-extract-year cursor-date))
(last (progn
(calendar-increment-month month year arg)
(calendar-last-day-of-month month year)))
(day (min last day))
;; Put the new month on the screen, if needed, and go to the new date.
(new-cursor-date (list month day year)))
(if (not (calendar-date-is-visible-p new-cursor-date))
(calendar-other-month month year))
(calendar-cursor-to-visible-date new-cursor-date))
(run-hooks 'calendar-move-hook))
;;;###cal-autoload
(defun calendar-backward-month (arg)
"Move the cursor backward by ARG months.
Movement is forward if ARG is negative."
(interactive "p")
(calendar-forward-month (- arg)))
;;;###cal-autoload
(defun calendar-forward-year (arg)
"Move the cursor forward by ARG years.
Movement is backward if ARG is negative."
(interactive "p")
(calendar-forward-month (* 12 arg)))
;;;###cal-autoload
(defun calendar-backward-year (arg)
"Move the cursor backward ARG years.
Movement is forward is ARG is negative."
(interactive "p")
(calendar-forward-month (* -12 arg)))
;;;###cal-autoload
(defun calendar-scroll-left (&optional arg event)
"Scroll the displayed calendar left by ARG months.
If ARG is negative the calendar is scrolled right. Maintains the relative
position of the cursor with respect to the calendar as well as possible.
EVENT is an event like `last-nonmenu-event'."
(interactive (list (prefix-numeric-value current-prefix-arg)
last-nonmenu-event))
(unless arg (setq arg 1))
(save-selected-window
;; Nil if called from menu-bar.
(if (setq event (event-start event)) (select-window (posn-window event)))
(calendar-cursor-to-nearest-date)
(unless (zerop arg)
(let ((old-date (calendar-cursor-to-date))
(today (calendar-current-date))
(month displayed-month)
(year displayed-year))
(calendar-increment-month month year arg)
(calendar-generate-window month year)
(calendar-cursor-to-visible-date
(cond
((calendar-date-is-visible-p old-date) old-date)
((calendar-date-is-visible-p today) today)
(t (list month 1 year))))))
(run-hooks 'calendar-move-hook)))
(define-obsolete-function-alias
'scroll-calendar-left 'calendar-scroll-left "23.1")
;;;###cal-autoload
(defun calendar-scroll-right (&optional arg event)
"Scroll the displayed calendar window right by ARG months.
If ARG is negative the calendar is scrolled left. Maintains the relative
position of the cursor with respect to the calendar as well as possible.
EVENT is an event like `last-nonmenu-event'."
(interactive (list (prefix-numeric-value current-prefix-arg)
last-nonmenu-event))
(calendar-scroll-left (- (or arg 1)) event))
(define-obsolete-function-alias
'scroll-calendar-right 'calendar-scroll-right "23.1")
Here's my take:
(defvar lawlist-month)
(defun lawlist-org-agenda-view-mode-dispatch ()
"Select the month in agenda view."
(interactive)
(message "View: [1-9] [o]CT [n]OV [d]EC, j(next), k(prev).")
(let* ((a (read-char-exclusive))
(month (case a
(?o 10)
(?n 11)
(?d 12)
(?j (or (and lawlist-month (mod (1+ lawlist-month) 12)) 1))
(?k (or (and lawlist-month (mod (1- lawlist-month) 12)) 1))
(t (and (> a ?0) (<= a ?9) (- a ?0))))))
(if (setq lawlist-month month)
(let ((year (nth 5 (decode-time (current-time)))))
(org-agenda nil "a")
(org-agenda-month-view
(read (format "%d%02d" year month)))
(calendar)
(calendar-other-month month year)
(lawlist-org-agenda-view-mode-dispatch))
(message "Aborted"))))
It still misses some functionality like saving the window configuration and
recovering on abort.
UPD
The updated code can be found in this gist.
I've added other years besides current, with support for j/k, as well as h/l for years.