Display yearly ical events from first year on. Fix Bug#23100.
Convert yearly rrule starting in year x into diary-anniversary entry for year x-1 when importing an icalendar. Correspondingly convert diary-anniversary for year x into yearly rrule starting in year x+1. * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-american: * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-european: * test/lisp/calendar/icalendar-resources/import-rrule-anniversary.diary-iso: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-american: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-european: * test/lisp/calendar/icalendar-resources/import-rrule-yearly.diary-iso: * test/lisp/calendar/icalendar-tests.el (icalendar-convert-anniversary-to-ical): Match new diary-anniversary/yearly-rrule behaviour. * lisp/calendar/icalendar.el (icalendar--datestring-to-isodate): Add year-shift option. (icalendar--convert-anniversary-to-ical): Shift the year as diary-anniversary is not displayed in the initial year. (icalendar--convert-recurring-to-diary): Shift the year as diary-anniversary is not displayed in the initial year. (Bug#23100)
This commit is contained in:
parent
211731b3a9
commit
899619ff6a
8 changed files with 85 additions and 65 deletions
|
@ -889,12 +889,14 @@ If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days."
|
|||
(format "%04d%02d%02d" (nth 2 mdy) (nth 0 mdy) (nth 1 mdy))))
|
||||
|
||||
|
||||
(defun icalendar--datestring-to-isodate (datestring &optional day-shift)
|
||||
(defun icalendar--datestring-to-isodate (datestring &optional day-shift year-shift)
|
||||
"Convert diary-style DATESTRING to iso-style date.
|
||||
If DAY-SHIFT is non-nil, the result is shifted by DAY-SHIFT days
|
||||
-- DAY-SHIFT must be either nil or an integer. This function
|
||||
tries to figure the date style from DATESTRING itself. If that
|
||||
is not possible it uses the current calendar date style."
|
||||
-- DAY-SHIFT must be either nil or an integer. If YEAR-SHIFT is
|
||||
non-nil, the result is shifted by YEAR-SHIFT years -- YEAR-SHIFT
|
||||
must be either nil or an integer. This function tries to figure
|
||||
the date style from DATESTRING itself. If that is not possible
|
||||
it uses the current calendar date style."
|
||||
(let ((day -1) month year)
|
||||
(save-match-data
|
||||
(cond ( ;; iso-style numeric date
|
||||
|
@ -904,7 +906,7 @@ is not possible it uses the current calendar date style."
|
|||
"0?\\([1-9][0-9]?\\)")
|
||||
datestring)
|
||||
(setq year (read (substring datestring (match-beginning 1)
|
||||
(match-end 1))))
|
||||
(match-end 1))))
|
||||
(setq month (read (substring datestring (match-beginning 2)
|
||||
(match-end 2))))
|
||||
(setq day (read (substring datestring (match-beginning 3)
|
||||
|
@ -967,6 +969,9 @@ is not possible it uses the current calendar date style."
|
|||
(match-end 3)))))
|
||||
(t
|
||||
nil)))
|
||||
(when year-shift
|
||||
(setq year (+ year year-shift)))
|
||||
|
||||
(if (> day 0)
|
||||
(let ((mdy (calendar-gregorian-from-absolute
|
||||
(+ (calendar-absolute-from-gregorian (list month day
|
||||
|
@ -1916,9 +1921,9 @@ entries. ENTRY-MAIN is the first line of the diary entry."
|
|||
(let* ((datetime (substring entry-main (match-beginning 1)
|
||||
(match-end 1)))
|
||||
(startisostring (icalendar--datestring-to-isodate
|
||||
datetime))
|
||||
datetime nil 1))
|
||||
(endisostring (icalendar--datestring-to-isodate
|
||||
datetime 1))
|
||||
datetime 1 1))
|
||||
(starttimestring (icalendar--diarytime-to-isotime
|
||||
(if (match-beginning 3)
|
||||
(substring entry-main
|
||||
|
@ -2402,8 +2407,11 @@ END-T is the event's end time in diary format."
|
|||
(if end-t "-" "")
|
||||
(or end-t ""))))
|
||||
(setq result (format
|
||||
"%%%%(and (diary-anniversary %s)) %s%s%s"
|
||||
dtstart-conv
|
||||
"%%%%(diary-anniversary %s) %s%s%s"
|
||||
(let* ((year (nth 5 dtstart-dec))
|
||||
(dtstart-1y-dec (copy-sequence dtstart-dec)))
|
||||
(setf (nth 5 dtstart-1y-dec) (1- year))
|
||||
(icalendar--datetime-to-diary-date dtstart-1y-dec))
|
||||
(or start-t "")
|
||||
(if end-t "-" "") (or end-t "")))))
|
||||
;; monthly
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 8 15 2004)) Maria Himmelfahrt
|
||||
&%%(diary-anniversary 8 15 2003) Maria Himmelfahrt
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 15 8 2004)) Maria Himmelfahrt
|
||||
&%%(diary-anniversary 15 8 2003) Maria Himmelfahrt
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 2004 8 15)) Maria Himmelfahrt
|
||||
&%%(diary-anniversary 2003 8 15) Maria Himmelfahrt
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 9 19 2003)) 09:00-11:30 rrule yearly
|
||||
&%%(diary-anniversary 9 19 2002) 09:00-11:30 rrule yearly
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 19 9 2003)) 09:00-11:30 rrule yearly
|
||||
&%%(diary-anniversary 19 9 2002) 09:00-11:30 rrule yearly
|
||||
|
|
|
@ -1 +1 @@
|
|||
&%%(and (diary-anniversary 2003 9 19)) 09:00-11:30 rrule yearly
|
||||
&%%(diary-anniversary 2002 9 19) 09:00-11:30 rrule yearly
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
(let* ((calendar-date-style 'iso)
|
||||
result)
|
||||
(setq result (icalendar--convert-anniversary-to-ical
|
||||
"" "%%(diary-anniversary 1964 6 30) g"))
|
||||
"" "%%(diary-anniversary 1963 6 30) g"))
|
||||
(should (consp result))
|
||||
(should (string= (concat
|
||||
"\nDTSTART;VALUE=DATE:19640630"
|
||||
|
@ -353,7 +353,7 @@ END:VTIMEZONE
|
|||
(let ((calendar-date-style 'iso))
|
||||
;; numeric iso
|
||||
(should (string= "20080511"
|
||||
(icalendar--datestring-to-isodate "2008 05 11")))
|
||||
(icalendar--datestring-to-isodate "2008 05 11")))
|
||||
(should (string= "20080531"
|
||||
(icalendar--datestring-to-isodate "2008 05 31")))
|
||||
(should (string= "20080602"
|
||||
|
@ -384,7 +384,19 @@ END:VTIMEZONE
|
|||
(should (string= "20081105"
|
||||
(icalendar--datestring-to-isodate "05 Nov 2008")))
|
||||
(should (string= "20081105"
|
||||
(icalendar--datestring-to-isodate "2008 Nov 05")))))
|
||||
(icalendar--datestring-to-isodate "2008 Nov 05")))
|
||||
|
||||
;; non-numeric with day-shift and year-shift
|
||||
(setq calendar-date-style nil) ;not necessary for conversion
|
||||
(should (string= "20210212"
|
||||
(icalendar--datestring-to-isodate "2021 Feb 11" 1)))
|
||||
(should (string= "20210131"
|
||||
(icalendar--datestring-to-isodate "2021 Feb 11" -11)))
|
||||
(should (string= "20200211"
|
||||
(icalendar--datestring-to-isodate "2021 Feb 11" nil -1)))
|
||||
(should (string= "21010211"
|
||||
(icalendar--datestring-to-isodate "2021 Feb 11" nil 80)))
|
||||
))
|
||||
|
||||
(ert-deftest icalendar--first-weekday-of-year ()
|
||||
"Test method for `icalendar-first-weekday-of-year'."
|
||||
|
@ -569,10 +581,10 @@ END:VEVENT
|
|||
|
||||
;; testcase: dtstart is mandatory
|
||||
(should (null (icalendar--convert-tz-offset
|
||||
'((TZOFFSETFROM nil "+0100")
|
||||
(TZOFFSETTO nil "+0200")
|
||||
(RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"))
|
||||
t)))
|
||||
'((TZOFFSETFROM nil "+0100")
|
||||
(TZOFFSETTO nil "+0200")
|
||||
(RRULE nil "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU"))
|
||||
t)))
|
||||
|
||||
;; FIXME: rrule and rdate are NOT mandatory! Must fix code
|
||||
;; before activating these testcases
|
||||
|
@ -830,18 +842,18 @@ SUMMARY:yearly no time
|
|||
"Perform export test."
|
||||
;; anniversaries
|
||||
(icalendar-tests--test-export
|
||||
"%%(diary-anniversary 1989 10 3) anniversary no time"
|
||||
"%%(diary-anniversary 3 10 1989) anniversary no time"
|
||||
"%%(diary-anniversary 10 3 1989) anniversary no time"
|
||||
"%%(diary-anniversary 1988 10 3) anniversary no time"
|
||||
"%%(diary-anniversary 3 10 1988) anniversary no time"
|
||||
"%%(diary-anniversary 10 3 1988) anniversary no time"
|
||||
"DTSTART;VALUE=DATE:19891003
|
||||
DTEND;VALUE=DATE:19891004
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03
|
||||
SUMMARY:anniversary no time
|
||||
")
|
||||
(icalendar-tests--test-export
|
||||
"%%(diary-anniversary 1989 10 3) 19:00-20:00 anniversary with time"
|
||||
"%%(diary-anniversary 3 10 1989) 19:00-20:00 anniversary with time"
|
||||
"%%(diary-anniversary 10 3 1989) 19:00-20:00 anniversary with time"
|
||||
"%%(diary-anniversary 1988 10 3) 19:00-20:00 anniversary with time"
|
||||
"%%(diary-anniversary 3 10 1988) 19:00-20:00 anniversary with time"
|
||||
"%%(diary-anniversary 10 3 1988) 19:00-20:00 anniversary with time"
|
||||
"DTSTART;VALUE=DATE-TIME:19891003T190000
|
||||
DTEND;VALUE=DATE-TIME:19891004T200000
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=10;BYMONTHDAY=03
|
||||
|
@ -891,12 +903,12 @@ SUMMARY:no alarm
|
|||
"
|
||||
nil)
|
||||
|
||||
;; 10 minutes in advance, audio
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 audio alarm"
|
||||
"17 Nov 2014 19:30 audio alarm"
|
||||
"Nov 17 2014 19:30 audio alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
;; 10 minutes in advance, audio
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 audio alarm"
|
||||
"17 Nov 2014 19:30 audio alarm"
|
||||
"Nov 17 2014 19:30 audio alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
DTEND;VALUE=DATE-TIME:20141117T203000
|
||||
SUMMARY:audio alarm
|
||||
BEGIN:VALARM
|
||||
|
@ -904,14 +916,14 @@ ACTION:AUDIO
|
|||
TRIGGER:-PT10M
|
||||
END:VALARM
|
||||
"
|
||||
'(10 ((audio))))
|
||||
'(10 ((audio))))
|
||||
|
||||
;; 20 minutes in advance, display
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 display alarm"
|
||||
"17 Nov 2014 19:30 display alarm"
|
||||
"Nov 17 2014 19:30 display alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
;; 20 minutes in advance, display
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 display alarm"
|
||||
"17 Nov 2014 19:30 display alarm"
|
||||
"Nov 17 2014 19:30 display alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
DTEND;VALUE=DATE-TIME:20141117T203000
|
||||
SUMMARY:display alarm
|
||||
BEGIN:VALARM
|
||||
|
@ -920,14 +932,14 @@ TRIGGER:-PT20M
|
|||
DESCRIPTION:display alarm
|
||||
END:VALARM
|
||||
"
|
||||
'(20 ((display))))
|
||||
'(20 ((display))))
|
||||
|
||||
;; 66 minutes in advance, email
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 email alarm"
|
||||
"17 Nov 2014 19:30 email alarm"
|
||||
"Nov 17 2014 19:30 email alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
;; 66 minutes in advance, email
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 email alarm"
|
||||
"17 Nov 2014 19:30 email alarm"
|
||||
"Nov 17 2014 19:30 email alarm"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
DTEND;VALUE=DATE-TIME:20141117T203000
|
||||
SUMMARY:email alarm
|
||||
BEGIN:VALARM
|
||||
|
@ -939,14 +951,14 @@ ATTENDEE:MAILTO:att.one@email.com
|
|||
ATTENDEE:MAILTO:att.two@email.com
|
||||
END:VALARM
|
||||
"
|
||||
'(66 ((email ("att.one@email.com" "att.two@email.com")))))
|
||||
'(66 ((email ("att.one@email.com" "att.two@email.com")))))
|
||||
|
||||
;; 2 minutes in advance, all alarms
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 all alarms"
|
||||
"17 Nov 2014 19:30 all alarms"
|
||||
"Nov 17 2014 19:30 all alarms"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
;; 2 minutes in advance, all alarms
|
||||
(icalendar-tests--test-export
|
||||
"2014 Nov 17 19:30 all alarms"
|
||||
"17 Nov 2014 19:30 all alarms"
|
||||
"Nov 17 2014 19:30 all alarms"
|
||||
"DTSTART;VALUE=DATE-TIME:20141117T193000
|
||||
DTEND;VALUE=DATE-TIME:20141117T203000
|
||||
SUMMARY:all alarms
|
||||
BEGIN:VALARM
|
||||
|
@ -967,7 +979,7 @@ TRIGGER:-PT2M
|
|||
DESCRIPTION:all alarms
|
||||
END:VALARM
|
||||
"
|
||||
'(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display)))))
|
||||
'(2 ((email ("att.one@email.com" "att.two@email.com")) (audio) (display)))))
|
||||
|
||||
;; ======================================================================
|
||||
;; Import tests
|
||||
|
@ -1247,7 +1259,7 @@ Argument INPUT icalendar event string."
|
|||
(find-file temp-ics)
|
||||
(goto-char (point-min))
|
||||
;;(when (re-search-forward "\nUID:.*\n" nil t)
|
||||
;;(replace-match "\n"))
|
||||
;;(replace-match "\n"))
|
||||
(let ((cycled (buffer-substring-no-properties (point-min) (point-max))))
|
||||
(should (string= org-input cycled)))))
|
||||
;; clean up
|
||||
|
@ -1276,8 +1288,8 @@ DESCRIPTION:beschreibung!
|
|||
LOCATION:nowhere
|
||||
ORGANIZER:ulf
|
||||
")
|
||||
(icalendar-tests--test-cycle
|
||||
"UID:4711
|
||||
(icalendar-tests--test-cycle
|
||||
"UID:4711
|
||||
DTSTART;VALUE=DATE:19190909
|
||||
DTEND;VALUE=DATE:19190910
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=09
|
||||
|
@ -1377,7 +1389,7 @@ SUMMARY:ff")
|
|||
"
|
||||
>>> anniversaries:
|
||||
|
||||
%%(diary-anniversary 3 28 1991) aa birthday (%d years old)"
|
||||
%%(diary-anniversary 3 28 1990) aa birthday (%d years old)"
|
||||
"DTSTART;VALUE=DATE:19910328
|
||||
DTEND;VALUE=DATE:19910329
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=03;BYMONTHDAY=28
|
||||
|
@ -1387,7 +1399,7 @@ SUMMARY:aa birthday (%d years old)
|
|||
(icalendar-tests--test-export
|
||||
nil
|
||||
nil
|
||||
"%%(diary-anniversary 5 17 1957) bb birthday (%d years old)"
|
||||
"%%(diary-anniversary 5 17 1956) bb birthday (%d years old)"
|
||||
"DTSTART;VALUE=DATE:19570517
|
||||
DTEND;VALUE=DATE:19570518
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=05;BYMONTHDAY=17
|
||||
|
@ -1396,7 +1408,7 @@ SUMMARY:bb birthday (%d years old)")
|
|||
(icalendar-tests--test-export
|
||||
nil
|
||||
nil
|
||||
"%%(diary-anniversary 6 8 1997) cc birthday (%d years old)"
|
||||
"%%(diary-anniversary 6 8 1996) cc birthday (%d years old)"
|
||||
"DTSTART;VALUE=DATE:19970608
|
||||
DTEND;VALUE=DATE:19970609
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=06;BYMONTHDAY=08
|
||||
|
@ -1405,7 +1417,7 @@ SUMMARY:cc birthday (%d years old)")
|
|||
(icalendar-tests--test-export
|
||||
nil
|
||||
nil
|
||||
"%%(diary-anniversary 7 22 1983) dd (%d years ago...!)"
|
||||
"%%(diary-anniversary 7 22 1982) dd (%d years ago...!)"
|
||||
"DTSTART;VALUE=DATE:19830722
|
||||
DTEND;VALUE=DATE:19830723
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=07;BYMONTHDAY=22
|
||||
|
@ -1414,7 +1426,7 @@ SUMMARY:dd (%d years ago...!)")
|
|||
(icalendar-tests--test-export
|
||||
nil
|
||||
nil
|
||||
"%%(diary-anniversary 8 1 1988) ee birthday (%d years old)"
|
||||
"%%(diary-anniversary 8 1 1987) ee birthday (%d years old)"
|
||||
"DTSTART;VALUE=DATE:19880801
|
||||
DTEND;VALUE=DATE:19880802
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=08;BYMONTHDAY=01
|
||||
|
@ -1423,7 +1435,7 @@ SUMMARY:ee birthday (%d years old)")
|
|||
(icalendar-tests--test-export
|
||||
nil
|
||||
nil
|
||||
"%%(diary-anniversary 9 21 1957) ff birthday (%d years old)"
|
||||
"%%(diary-anniversary 9 21 1956) ff birthday (%d years old)"
|
||||
"DTSTART;VALUE=DATE:19570921
|
||||
DTEND;VALUE=DATE:19570922
|
||||
RRULE:FREQ=YEARLY;INTERVAL=1;BYMONTH=09;BYMONTHDAY=21
|
||||
|
|
Loading…
Add table
Reference in a new issue