From: Richard Lawrence Date: Sun, 11 May 2025 05:47:42 +0000 (+0200) Subject: Fix DTSTART date when exporting `diary-float' X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a34ee34dae491d3969f5fba6b7c20913994b922e;p=emacs.git Fix DTSTART date when exporting `diary-float' Instead of using current date as DTSTART and then excluding it when it doesn't match the `diary-float' rule, just use the first date which matches the rule in `icalendar-recurring-start-year'. * lisp/calendar/icalendar.el (icalendar--convert-float-to-ical): Compute the correct date. * test/lisp/calendar/icalendar-tests.el: Add a test for the reported test case. (Bug#78085) (cherry picked from commit c1153963b5db351d3fbe8f661e17efb55ebb2cb8) --- diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index a1341248fce..2c49557a303 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -1766,10 +1766,19 @@ entries. ENTRY-MAIN is the first line of the diary entry." ;matching, esp. with ;different forms of ;MONTH - (month (nth 1 sexp)) + (month-exp (nth 1 sexp)) + (months (cond ((eq month-exp t) nil) ; don't add a BYMONTH clause + ((integerp month-exp) (list month-exp)) + (t month-exp))) (dayname (nth 2 sexp)) (n (nth 3 sexp)) (day (nth 4 sexp)) + (dtstart + ;; Start on the first day matching the rule in + ;; icalendar-recurring-start-year: + (calendar-nth-named-day n dayname + (if months (apply #'min months) 1) + icalendar-recurring-start-year)) (summary (replace-regexp-in-string "\\(^\s+\\|\s+$\\)" "" @@ -1781,31 +1790,19 @@ entries. ENTRY-MAIN is the first line of the diary entry." (error "Don't know if or how to implement day in `diary-float'"))) (cons (concat - ;;Start today (yes this is an arbitrary choice): "\nDTSTART;VALUE=DATE:" - (format-time-string "%Y%m%d") - ;;BUT remove today if `diary-float' - ;;expression does not hold true for today: - (when - (null (calendar-dlet ((date (calendar-current-date)) - (entry entry-main)) - (diary-float month dayname n))) - (concat - "\nEXDATE;VALUE=DATE:" - (format-time-string "%Y%m%d"))) + (format "%04d%02d%02d" + (calendar-extract-year dtstart) + (calendar-extract-month dtstart) + (calendar-extract-day dtstart)) "\nRRULE:" - (if (or (numberp month) (listp month)) + (if months "FREQ=YEARLY;BYMONTH=" "FREQ=MONTHLY") - (when - (listp month) + (when months (mapconcat - (lambda (m) - (number-to-string m)) - (cadr month) ",")) - (when - (numberp month) - (number-to-string month)) + (lambda (m) (number-to-string m)) + months ",")) ";BYDAY=" (number-to-string n) (aref icalendar--weekday-array dayname)) diff --git a/test/lisp/calendar/icalendar-tests.el b/test/lisp/calendar/icalendar-tests.el index 421c991bcac..5e745c05d0a 100644 --- a/test/lisp/calendar/icalendar-tests.el +++ b/test/lisp/calendar/icalendar-tests.el @@ -132,6 +132,22 @@ (car result))) (should (string= "Sommerferien" (cdr result))))) +(ert-deftest icalendar--convert-float-to-ical () + "Test method for `icalendar--convert-float-to-ical'." + ;; See Bug#78085 + (let* ((calendar-date-style 'iso) + (icalendar-recurring-start-year 2025) + (first-saturday-date "20250104") ; first Sat. in 2025 + result) + (setq result (icalendar--convert-float-to-ical + "" "%%(diary-float t 6 1) 1st Sat/month")) + (should (consp result)) + (should (string= (concat + "\nDTSTART;VALUE=DATE:" first-saturday-date + "\nRRULE:FREQ=MONTHLY;BYDAY=1SA") + (car result))) + (should (string= "1st Sat/month" (cdr result))))) + (ert-deftest icalendar--convert-yearly-to-ical () "Test method for `icalendar--convert-yearly-to-ical'." (let* ((calendar-date-style 'iso)