如何在agenda list里面显示一个人的农历生日? 最好是可以显示年龄的。 就像下面这样可以显示阳历生日一样。 %%(diary-anniversary 2 7 1948) Arthur’s %d%s birthday
换成 diary-chinese-anniversary
应该就行,我刚刚试了下。
我这里出现错误啊,不知道什么原因,显示bad sexp
噢,设置年份的话,确实会有错误(Bad sexp)。只设置月日的话就没问题。不清楚怎么一回事。
好吧,年份不是按公历记的,比如公历 1993 年大致对应的是 7810。下面在我这有效:
* 某人的生日
%%(diary-chinese-anniversary 9 23 7810) 这是农历 1993 年 9 月 23 日生人的第 %d%s 个生日
(我对农历一无所知,不清楚 7810 是怎么回事。我是把先将农历 1993/9/23 转化成公历 1993/11/6,然后到 M-x calendar
里面,按 g d
跳到这个日期,最后在按 p C
得出 7810)
不清楚 7810 是怎么回事
上下5000年?
农历年份以 60 年为一个周期,按公元前 2637 年算起的话,则 1993 年处于第 78
个周期中的第 10
年。
(let* ((cycle (/ (+ 1993 2637) 60.0))
(year (- (+ 1993 2637) (* 60 (truncate cycle)))))
(list (ceiling cycle) year))
=> (78 10)
参考:
%%(diary-chinese-anniversary 2 7 7810) ABC’s %d%s birthday 这样写没有报错,但是在agenda list里面没有出现变化啊,没有这个事项啊。
我失误了,忘记了,抱歉,谢谢你的回答。
周期的计算有点小问题,要向下取整加1
(let* ((cycle (/ (+ 1993 2637) 60.0))
(year (- (+ 1993 2637) (* 60 (truncate cycle)))))
(list (+ 1 (floor cycle)) year))
=> (78 10)
能不能直接这么写 %%(diary-chinese-anniversary 9 23 1993) 这是农历 1993 年 9 月 23 日生人的第 %d%s 个生日 然后用你写的这段代码来防止emacs报错啊?免得每次还要再计算一下cycle和year。
加上这段:
(defun diary-chinese-anniversary (lunar-month lunar-day &optional year mark)
(let* ((ddate (diary-make-date lunar-month lunar-day year))
(dd (calendar-extract-day ddate))
(mm (calendar-extract-month ddate))
(yy (calendar-extract-year ddate))
(a-date (calendar-absolute-from-gregorian date))
(c-date (calendar-chinese-from-absolute a-date))
(mm2 (nth 2 c-date))
(dd2 (nth 3 c-date))
(y (calendar-extract-year date))
(diff (if year (- y year) 100)))
(and (> diff 0) (= mm mm2) (= dd dd2)
(cons mark (format entry diff (diary-ordinal-suffix diff))))))
然后就可以这样撸农历了
%%(diary-chinese-anniversary 9 23 1993) 这是农历 1993 年 9 月 23 日生人的第 %d%s 个生日
运行出现问题,这段代码的适用范围是多少啊?我对这段代码不熟悉。
直接覆盖diary-chinese-anniversary可能造成问题,可以改个名字,再利用自带的diary-chinese-anniversary
(defun my--diary-chinese-anniversary (lunar-month lunar-day &optional year mark)
(if year
(let* ((d-date (diary-make-date lunar-month lunar-day year))
(a-date (calendar-absolute-from-gregorian d-date))
(c-date (calendar-chinese-from-absolute a-date))
(cycle (car c-date))
(yy (cadr c-date))
(y (+ (* 100 cycle) yy)))
(diary-chinese-anniversary lunar-month lunar-day y mark))
(diary-chinese-anniversary lunar-month lunar-day year mark)))
然后这样写 %%(my–diary-chinese-anniversary 9 23 1993) 这是农历 1993 年 9 月 23 日生人的第 %d%s 个生日
目前运行正常,非常感谢。
这段代码有一个小问题:emacs25.1
可以用,emacs24.5
会运行出错,我不懂lisp
语言,所以不知道怎么修改。
有个包叫cal-china-x
,这个包有个函数holiday-lunar
,可以直接定义农历节日。
不仅如此,通过配置,它还能在日历上显示农历。
安装了这个包后,可以用如下函数进行农历和公历转换:
(defun date-to-lunar-date (date)
"把calendar表示的公历日期转换成农历日期"
(calendar-chinese-from-absolute
(calendar-absolute-from-gregorian date)))
date是个list,具体什么结构我忘记了,试一下就知道了。
自带的 diary-chinese-anniversary
是不是有问题?有一个 undefined 的变量 date
;;;###cal-autoload
(defun diary-chinese-anniversary (month day &optional year mark)
"Like `diary-anniversary' (which see) but accepts Chinese date."
(pcase-let* ((ddate (diary-make-date month day year))
(`(,dc ,dy ,dm ,dd) ;diary chinese date
(if year
(calendar-chinese-from-absolute
(calendar-chinese-to-absolute-for-diary ddate))
(list nil nil (calendar-extract-month ddate)
(calendar-extract-day ddate))))
(`(,cc ,cy ,cm ,cd) ;current chinese date
(calendar-chinese-from-absolute
(calendar-absolute-from-gregorian date)))
(diff (if (and dc dy)
(+ (* 60 (- cc dc)) (- cy dy))
100)))
(and (> diff 0)
;; The Chinese month can differ by 0.5 in a leap month.
(or (= dm cm) (= (+ 0.5 dm) cm))
(= dd cd)
(cons mark (format entry diff (diary-ordinal-suffix diff))))))