]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix DTSTART date when exporting `diary-float'
authorRichard Lawrence <rwl@recursewithless.net>
Sun, 11 May 2025 05:47:42 +0000 (07:47 +0200)
committerEshel Yaron <me@eshelyaron.com>
Tue, 20 May 2025 20:52:40 +0000 (22:52 +0200)
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)

lisp/calendar/icalendar.el
test/lisp/calendar/icalendar-tests.el

index a1341248fce57f42e2f882faa809bf49647ec5bc..2c49557a303d9e4a3b69a1a318d0817cc0f71ec2 100644 (file)
@@ -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))
index 421c991bcacce0279f55aeb11d612bc00e283ccf..5e745c05d0a633c627e5b7cef592659889429002 100644 (file)
                      (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)