unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Lars Ingebrigtsen <larsi@gnus.org>
To: thunk2@arcor.de (Thomas Plass)
Cc: 34315@debbugs.gnu.org, Jan Tatarik <jan.tatarik@gmail.com>
Subject: bug#34315: [PATCH] icalendar.el: DURATION fix + more robust timezone handling
Date: Thu, 01 Oct 2020 03:45:59 +0200	[thread overview]
Message-ID: <874knewwfc.fsf@gnus.org> (raw)
In-Reply-To: <24435.1743.473339.944597@AGAME7.local> (Thomas Plass's message of "Tue, 29 Sep 2020 12:05:03 +0200")

[-- Attachment #1: Type: text/plain, Size: 1080 bytes --]

thunk2@arcor.de (Thomas Plass) writes:

>  - in celebration, I'd like to submit yet another patch that extends
>    icalendar.el's timezone handling, this one intended to support
>    regions that at some point in the past made a permanent switch from
>    a DST/STD scheme to STD-only/DST-only.  Cases in point are China
>    and Turkey,
>    cf. https://en.wikipedia.org/wiki/Daylight_saving_time_in_Asia.
>
>    Ulf, would you care to review the code and the included test cases?

Thanks for the code.  It was in slightly inconvenient format -- we
prefer just simple patches, so I've reformatted it as such below.

However, the code makes two tests fail:

2 unexpected results:
   FAILED  icalendar--convert-tz-offset
   FAILED  icalendar--parse-vtimezone

I haven't actually looked at the failing cases, though.

In addition, the test cases included aren't actually used?  Could you
propose some code to use them?  (It should go in
test/lisp/calendar/icalendar-tests.el.)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: icalendar.patch --]
[-- Type: text/x-diff, Size: 18249 bytes --]

diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index dab277487e..e4760db3e4 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -519,46 +519,56 @@ icalendar--convert-tz-offset
 	 (dtstart (car (cddr (assq 'DTSTART alist))))
 	 (no-dst (or rdate-p (equal offsetto offsetfrom))))
     ;; FIXME: the presence of an RDATE is assumed to denote the first day of the year
-    (when (and offsetto dtstart (or rrule-value no-dst))
-      (let* ((rrule (icalendar--split-value rrule-value))
-	     (freq (cadr (assq 'FREQ rrule)))
-	     (bymonth (cadr (assq 'BYMONTH rrule)))
-	     (byday (cadr (assq 'BYDAY rrule))))
-	;; FIXME: we don't correctly handle WKST here.
-	(if (or no-dst (and (string= freq "YEARLY") bymonth))
-	    (cons
-	     (concat
-	      ;; Fake a name.
-	      (if dst-p "DST" "STD")
-	      ;; For TZ, OFFSET is added to the local time.  So,
-	      ;; invert the values.
-	      (if (eq (aref offsetto 0) ?-) "+" "-")
-	      (substring offsetto 1 3)
-	      ":"
-	      (substring offsetto 3 5))
-	     ;; The start time.
-             (let* ((day (if no-dst
-                             1
-                           (icalendar--get-weekday-number (substring byday -2))))
-                    (week (if no-dst
-                              "1"
-                            (if (eq day -1)
-				byday
-			      (substring byday 0 -2)))))
-		 ;; "Translate" the iCalendar way to specify the last
-		 ;; (sun|mon|...)day in month to the tzset way.
-		 (if (string= week "-1")  ; last day as iCalendar calls it
+    (if (and offsetto dtstart (or rrule-value no-dst))
+        (let* ((rrule (icalendar--split-value rrule-value))
+	       (freq (cadr (assq 'FREQ rrule)))
+	       (bymonth (cadr (assq 'BYMONTH rrule)))
+	       (byday (cadr (assq 'BYDAY rrule))))
+	  ;; FIXME: we don't correctly handle WKST here.
+	  (if (or no-dst (and (string= freq "YEARLY") bymonth))
+	      (cons
+	       (concat
+	        ;; Fake a name.
+	        (if dst-p "DST" "STD")
+	        ;; For TZ, OFFSET is added to the local time.  So,
+	        ;; invert the values.
+	        (if (eq (aref offsetto 0) ?-) "+" "-")
+	        (substring offsetto 1 3)
+	        ":"
+	        (substring offsetto 3 5))
+	       ;; The start time.
+               (let* ((day (if no-dst
+                               1
+                             (icalendar--get-weekday-number (substring byday -2))))
+                      (week (if no-dst
+                                "1"
+                              (if (eq day -1)
+				  byday
+			        (substring byday 0 -2)))))
+	         ;; "Translate" the iCalendar way to specify the last
+	         ;; (sun|mon|...)day in month to the tzset way.
+	         (if (string= week "-1")  ; last day as iCalendar calls it
 		     (setq week "5"))     ; last day as tzset calls it
                  (when no-dst (setq bymonth "1"))
 		 (concat "M" bymonth "." week "." (if (eq day -1) "0"
 						    (int-to-string day))
-			 ;; Start time.
-			 "/"
-			 (substring dtstart -6 -4)
-			 ":"
-			 (substring dtstart -4 -2)
-			 ":"
-			 (substring dtstart -2)))))))))
+		         ;; Start time.
+		         "/"
+		         (substring dtstart -6 -4)
+		         ":"
+		         (substring dtstart -4 -2)
+		         ":"
+		         (substring dtstart -2))))))
+      ;; neither RRULE nor RDATE present: return the offset and a placeholder
+      (cons
+       (concat
+	;; Fake a name.
+	(if dst-p "DST" "STD")
+	(if (eq (aref offsetto 0) ?-) "+" "-")
+	(substring offsetto 1 3)
+	":"
+	(substring offsetto 3 5))
+       dtstart))))
 
 (defun icalendar--parse-vtimezone (alist)
   "Turn a VTIMEZONE ALIST into a cons (ID . TZ-STRING).
@@ -571,34 +581,59 @@ icalendar--parse-vtimezone
 	 (standard (cadr (cdar (icalendar--get-most-recent-observance alist 'STANDARD))))
 	 (std (and standard (icalendar--convert-tz-offset standard nil))))
     (if (and tz-id std)
-	(cons tz-id
-	      (if day
-		  (concat (car std) (car day)
-			  "," (cdr day) "," (cdr std))
-		(car std))))))
+        (cons tz-id
+              (if (and (not (assq 'RRULE daylight))
+                       (not (assq 'RRULE standard)))
+                  (let ((daylight-rdate (and (assq 'RDATE daylight)
+                                             (icalendar--get-most-recent-observance-from-sub-comp
+                                              daylight
+                                              '(RDATE))))
+                        (standard-rdate (and (assq 'RDATE standard)
+                                             (icalendar--get-most-recent-observance-from-sub-comp
+                                              standard
+                                              '(RDATE)))))
+                    (if (and daylight-rdate
+                             standard-rdate
+                             (string-greaterp daylight-rdate standard-rdate))
+                        (car day)
+                      (car std)))
+	        (if day
+		    (concat (car std) (car day)
+			    "," (cdr day) "," (cdr std))
+		  (car std)))))))
 
 (defun icalendar--get-most-recent-observance (alist sub-comp)
-  "Return the latest observance for SUB-COMP DAYLIGHT or STANDARD.
+  "Return the latest observance of all SUB-COMPs DAYLIGHT or STANDARD.
 ALIST is a VTIMEZONE potentially containing historical records."
-;FIXME?: "most recent" should be relative to a given date
+;FIXME: "most recent" should be relative to a given date and
+;       avoid selecting a SUB-COMP valid for dates in the future.
   (let ((components (icalendar--get-children alist sub-comp)))
     (list
      (car
       (sort components
             #'(lambda (a b)
-                (let* ((get-recent (lambda (n)
-                                     (car
-                                      (sort
-                                       (delq nil
-                                             (mapcar (lambda (p)
-                                                       (and (memq (car p) '(DTSTART RDATE))
-                                                            (car (cddr p))))
-                                                     n))
-                                       'string-greaterp))))
-                       (a-recent (funcall get-recent (car (cddr a))))
-                       (b-recent (funcall get-recent (car (cddr b)))))
+                (let* ((a-recent (icalendar--get-most-recent-observance-from-sub-comp
+                                  (car (cddr a))
+                                  '(DTSTART RDATE)))
+                       (b-recent (icalendar--get-most-recent-observance-from-sub-comp
+                                  (car (cddr b))
+                                  '(DTSTART RDATE))))
                   (string-greaterp a-recent b-recent))))))))
 
+(defun icalendar--get-most-recent-observance-from-sub-comp (alist sym-list)
+  "Return the latest observance for ALIST DAYLIGHT or STANDARD.
+ALIST is an individual DAYLIGHT or STANDARD.
+SYM-LIST is a list of property names DTSTART and/or RDATE
+for filtering ALIST."
+  (car
+   (sort
+    (delq nil
+          (mapcar (lambda (p)
+                    (when (memq (car p) sym-list)
+                      (car (cddr p))))
+                  alist))
+    'string-greaterp)))
+
 (defun icalendar--convert-all-timezones (icalendar)
   "Convert all timezones in the ICALENDAR into an alist.
 Each element of the alist is a cons (ID . TZ-STRING),
diff --git a/test/lisp/calendar/icalendar-resources/Asia_Istanbul_20200924T120000_in-calendar_VTIMEZONE_tzurl_org.ics b/test/lisp/calendar/icalendar-resources/Asia_Istanbul_20200924T120000_in-calendar_VTIMEZONE_tzurl_org.ics
new file mode 100644
index 0000000000..6425909be6
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/Asia_Istanbul_20200924T120000_in-calendar_VTIMEZONE_tzurl_org.ics
@@ -0,0 +1,219 @@
+BEGIN:VCALENDAR

+PRODID:manual

+VERSION:2.0

+BEGIN:VTIMEZONE

+TZID:Asia/Istanbul

+TZURL:http://tzurl.org/zoneinfo/Asia/Istanbul

+X-LIC-LOCATION:Asia/Istanbul

+BEGIN:STANDARD

+TZOFFSETFROM:+015552

+TZOFFSETTO:+015656

+TZNAME:IMT

+DTSTART:18800101T000000

+RDATE:18800101T000000

+END:STANDARD

+BEGIN:STANDARD

+TZOFFSETFROM:+015656

+TZOFFSETTO:+0200

+TZNAME:EET

+DTSTART:19101001T000000

+RDATE:19101001T000000

+END:STANDARD

+BEGIN:DAYLIGHT

+TZOFFSETFROM:+0200

+TZOFFSETTO:+0300

+TZNAME:EEST

+DTSTART:19160501T000000

+RDATE:19160501T000000

+RDATE:19200328T000000

+RDATE:19210403T000000

+RDATE:19220326T000000

+RDATE:19240513T000000

+RDATE:19250501T000000

+RDATE:19400630T000000

+RDATE:19401201T000000

+RDATE:19420401T000000

+RDATE:19450402T000000

+RDATE:19460601T000000

+RDATE:19470420T000000

+RDATE:19480418T000000

+RDATE:19490410T000000

+RDATE:19500419T000000

+RDATE:19510422T000000

+RDATE:19620715T000000

+RDATE:19640515T000000

+RDATE:19700503T000000

+RDATE:19710502T000000

+RDATE:19720507T000000

+RDATE:19730603T010000

+RDATE:19740331T020000

+RDATE:19750330T000000

+RDATE:19760601T000000

+RDATE:19770403T000000

+RDATE:19780402T000000

+RDATE:19860330T010000

+RDATE:19870329T010000

+RDATE:19880327T010000

+RDATE:19890326T010000

+RDATE:19900325T010000

+RDATE:19910331T010000

+RDATE:19920329T010000

+RDATE:19930328T010000

+RDATE:19940320T010000

+RDATE:19950326T010000

+RDATE:19960331T010000

+RDATE:19970330T010000

+RDATE:19980329T010000

+RDATE:19990328T010000

+RDATE:20000326T010000

+RDATE:20010325T010000

+RDATE:20020331T010000

+RDATE:20030330T010000

+RDATE:20040328T010000

+RDATE:20050327T010000

+RDATE:20060326T010000

+RDATE:20070325T030000

+RDATE:20080330T030000

+RDATE:20090329T030000

+RDATE:20100328T030000

+RDATE:20110328T030000

+RDATE:20120325T030000

+RDATE:20130331T030000

+RDATE:20140331T030000

+RDATE:20150329T030000

+RDATE:20160327T030000

+END:DAYLIGHT

+BEGIN:STANDARD

+TZOFFSETFROM:+0300

+TZOFFSETTO:+0200

+TZNAME:EET

+DTSTART:19161001T000000

+RDATE:19161001T000000

+RDATE:19201025T000000

+RDATE:19211003T000000

+RDATE:19221008T000000

+RDATE:19241001T000000

+RDATE:19251001T000000

+RDATE:19401005T000000

+RDATE:19410921T000000

+RDATE:19421101T000000

+RDATE:19451008T000000

+RDATE:19461001T000000

+RDATE:19471005T000000

+RDATE:19481003T000000

+RDATE:19491002T000000

+RDATE:19501008T000000

+RDATE:19511008T000000

+RDATE:19621008T000000

+RDATE:19641001T000000

+RDATE:19701004T000000

+RDATE:19711003T000000

+RDATE:19721008T000000

+RDATE:19731104T030000

+RDATE:19741103T050000

+RDATE:19751026T000000

+RDATE:19761031T000000

+RDATE:19771016T000000

+RDATE:19850928T000000

+RDATE:19860928T020000

+RDATE:19870927T020000

+RDATE:19880925T020000

+RDATE:19890924T020000

+RDATE:19900930T020000

+RDATE:19910929T020000

+RDATE:19920927T020000

+RDATE:19930926T020000

+RDATE:19940925T020000

+RDATE:19950924T020000

+RDATE:19961027T020000

+RDATE:19971026T020000

+RDATE:19981025T020000

+RDATE:19991031T020000

+RDATE:20001029T020000

+RDATE:20011028T020000

+RDATE:20021027T020000

+RDATE:20031026T020000

+RDATE:20041031T020000

+RDATE:20051030T020000

+RDATE:20061029T020000

+RDATE:20071028T040000

+RDATE:20081026T040000

+RDATE:20091025T040000

+RDATE:20101031T040000

+RDATE:20111030T040000

+RDATE:20121028T040000

+RDATE:20131027T040000

+RDATE:20141026T040000

+END:STANDARD

+BEGIN:DAYLIGHT

+TZOFFSETFROM:+0300

+TZOFFSETTO:+0400

+TZNAME:+04

+DTSTART:19781015T000000

+RDATE:19781015T000000

+RDATE:19800406T030000

+RDATE:19810329T030000

+RDATE:19820328T030000

+RDATE:19830731T000000

+END:DAYLIGHT

+BEGIN:DAYLIGHT

+TZOFFSETFROM:+0400

+TZOFFSETTO:+0400

+TZNAME:+04

+DTSTART:19790401T030000

+RDATE:19790401T030000

+END:DAYLIGHT

+BEGIN:STANDARD

+TZOFFSETFROM:+0400

+TZOFFSETTO:+0300

+TZNAME:+03

+DTSTART:19791015T000000

+RDATE:19791015T000000

+RDATE:19801013T000000

+RDATE:19811012T000000

+RDATE:19821011T000000

+RDATE:19831002T000000

+END:STANDARD

+BEGIN:DAYLIGHT

+TZOFFSETFROM:+0300

+TZOFFSETTO:+0300

+TZNAME:EEST

+DTSTART:19850420T000000

+RDATE:19850420T000000

+RDATE:20151025T040000

+END:DAYLIGHT

+BEGIN:STANDARD

+TZOFFSETFROM:+0200

+TZOFFSETTO:+0200

+TZNAME:EET

+DTSTART:20070101T000000

+RDATE:20070101T000000

+RDATE:20110327T030000

+RDATE:20140330T030000

+END:STANDARD

+BEGIN:STANDARD

+TZOFFSETFROM:+0300

+TZOFFSETTO:+0200

+DTSTART:20151108T040000

+RDATE:20151108T040000

+END:STANDARD

+BEGIN:STANDARD

+TZOFFSETFROM:+0300

+TZOFFSETTO:+0300

+TZNAME:+03

+DTSTART:20160907T000000

+RDATE:20160907T000000

+END:STANDARD

+END:VTIMEZONE

+BEGIN:VEVENT

+CLASS:PUBLIC

+DTSTART;TZID=Asia/Istanbul:20200924T120000

+DTEND;TZID=Asia/Istanbul:20200924T130000

+UID:Asia_Istanbul_20200924T120000_in-calendar_VTIMEZONE_tzurl_org.ics

+DTSTAMP:20190127T140400

+DESCRIPTION:date 2020-09-24, Istanbul local time 12:00 UTC+3, in-calendar

+  VTIMEZONE as returned by http://tzurl.org/zoneinfo/Asia/Istanbul

+SUMMARY:date 2020-09-24, Istanbul local time 12:00 UTC+3, in-calendar

+  VTIMEZONE as returned by http://tzurl.org/zoneinfo/Asia/Istanbul

+END:VEVENT

+END:VCALENDAR

diff --git a/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_multi_DAYLIGHT_STANDARD.ics b/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_multi_DAYLIGHT_STANDARD.ics
new file mode 100644
index 0000000000..26dd3cbfb8
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_multi_DAYLIGHT_STANDARD.ics
@@ -0,0 +1,116 @@
+BEGIN:VCALENDAR

+PRODID:manual

+VERSION:2.0

+CALSCALE:GREGORIAN

+METHOD:PUBLISH

+BEGIN:VTIMEZONE

+TZID:Asia/Shanghai

+X-LIC-LOCATION:Asia/Shanghai

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19411001T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19860504T000000

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19860914T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19870412T000000

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19870913T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19880410T000000

+TZOFFSETFROM:+0800

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19880911T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19890416T000000

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19890917T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19900415T000000

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19900916T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+BEGIN:DAYLIGHT

+TZNAME:CDT

+DTSTART:19910414T000000

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+END:DAYLIGHT

+BEGIN:STANDARD

+TZNAME:CST

+DTSTART:19910915T000000

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+END:STANDARD

+END:VTIMEZONE

+BEGIN:VTIMEZONE

+TZID:Etc/UTC

+X-LIC-LOCATION:Etc/UTC

+BEGIN:STANDARD

+TZNAME:UTC

+DTSTART:19700101T000000

+TZOFFSETFROM:+0000

+TZOFFSETTO:+0000

+END:STANDARD

+END:VTIMEZONE

+BEGIN:VEVENT

+CLASS:PUBLIC

+DTSTART;TZID=Asia/Shanghai:20200916T070000

+DTEND;TZID=Asia/Shanghai:20200916T080000

+UID:Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_multi_DAYLIGHT_STANDARD.ics

+DTSTAMP:20190127T140400

+DESCRIPTION:date 2020-09-16, Shanghai local time 07:00 UTC+8, in-calendar

+  VTIMEZONE with multiple DAYLIGHT and STANDARD sub-components, cf.

+ https://techcommunity.microsoft.com/t5/office-365/import-ics-to-office-365

+ -calendar-but-the-event-time-is-wrong/td-p/215332

+SUMMARY:date 2020-09-16, Shanghai local time 07:00 UTC+8, in-calendar

+  VTIMEZONE with multiple DAYLIGHT and STANDARD sub-components, cf.

+ https://techcommunity.microsoft.com/t5/office-365/import-ics-to-office-365

+ -calendar-but-the-event-time-is-wrong/td-p/215332

+END:VEVENT

+END:VCALENDAR

+

+ 

diff --git a/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_tzurl_org.ics b/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_tzurl_org.ics
new file mode 100644
index 0000000000..ccd39bd114
--- /dev/null
+++ b/test/lisp/calendar/icalendar-resources/Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_tzurl_org.ics
@@ -0,0 +1,65 @@
+BEGIN:VCALENDAR

+PRODID:manual

+VERSION:2.0

+BEGIN:VTIMEZONE

+TZID:Asia/Shanghai

+TZURL:http://tzurl.org/zoneinfo/Asia/Shanghai

+X-LIC-LOCATION:Asia/Shanghai

+BEGIN:STANDARD

+TZOFFSETFROM:+080543

+TZOFFSETTO:+0800

+TZNAME:CST

+DTSTART:19010101T000000

+RDATE:19010101T000000

+END:STANDARD

+BEGIN:DAYLIGHT

+TZOFFSETFROM:+0800

+TZOFFSETTO:+0900

+TZNAME:CDT

+DTSTART:19400601T000000

+RDATE:19400601T000000

+RDATE:19410315T000000

+RDATE:19420131T000000

+RDATE:19460515T000000

+RDATE:19470415T000000

+RDATE:19480501T000000

+RDATE:19490501T000000

+RDATE:19860504T020000

+RDATE:19870412T020000

+RDATE:19880417T020000

+RDATE:19890416T020000

+RDATE:19900415T020000

+RDATE:19910414T020000

+END:DAYLIGHT

+BEGIN:STANDARD

+TZOFFSETFROM:+0900

+TZOFFSETTO:+0800

+TZNAME:CST

+DTSTART:19401012T235959

+RDATE:19401012T235959

+RDATE:19411101T235959

+RDATE:19450901T235959

+RDATE:19460930T235959

+RDATE:19471031T235959

+RDATE:19480930T235959

+RDATE:19490528T000000

+RDATE:19860914T020000

+RDATE:19870913T020000

+RDATE:19880911T020000

+RDATE:19890917T020000

+RDATE:19900916T020000

+RDATE:19910915T020000

+END:STANDARD

+END:VTIMEZONE

+BEGIN:VEVENT

+CLASS:PUBLIC

+DTSTART;TZID=Asia/Shanghai:20200916T070000

+DTEND;TZID=Asia/Shanghai:20200916T080000

+UID:Asia_Shanghai_20200916T070000_in-calendar_VTIMEZONE_tzurl_org.ics

+DTSTAMP:20190127T140400

+DESCRIPTION:date 2020-09-16, Shanghai local time 07:00 UTC+8, in-calendar

+  VTIMEZONE as returned by http://tzurl.org/zoneinfo/Asia/Shanghai

+SUMMARY:date 2020-09-16, Shanghai local time 07:00 UTC+8, in-calendar

+  VTIMEZONE as returned by http://tzurl.org/zoneinfo/Asia/Shanghai

+END:VEVENT

+END:VCALENDAR


  reply	other threads:[~2020-10-01  1:45 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-04 11:48 bug#34315: [PATCH] icalendar.el: DURATION fix + more robust timezone handling Thomas Plass
2019-02-12 18:57 ` Ulf Jasper
2019-02-15 17:17   ` Ulf Jasper
2019-02-18  9:36     ` Thomas Plass
2019-02-18 15:59       ` Eli Zaretskii
2019-02-18 19:15         ` Thomas Plass
2019-02-18 19:30           ` Eli Zaretskii
2019-02-18 20:03             ` Thomas Plass
2019-02-18 20:16               ` Eli Zaretskii
2020-08-10 11:48     ` Lars Ingebrigtsen
2020-08-10 16:08       ` Ulf Jasper
2020-08-10 16:45         ` Eli Zaretskii
2020-08-10 17:04           ` Thomas Plass
2020-08-11 11:01             ` Lars Ingebrigtsen
2020-08-11 15:14               ` Ulf Jasper
2020-08-11 15:19                 ` Lars Ingebrigtsen
2020-08-11 15:45                   ` Ulf Jasper
2020-08-12 13:08                 ` Thomas Plass
2020-08-12 13:12                   ` Lars Ingebrigtsen
2020-08-12 13:30                     ` Thomas Plass
2020-08-12 15:06                       ` Ulf Jasper
2020-09-02 18:05                         ` Ulf Jasper
2020-09-03  8:38                           ` Thomas Plass
2020-09-03 14:28                             ` Ulf Jasper
2020-09-12  8:01                               ` Thomas Plass
2020-09-12  8:11                                 ` Eli Zaretskii
2020-09-13  4:07                                 ` Richard Stallman
2020-09-29 10:05                               ` Thomas Plass
2020-10-01  1:45                                 ` Lars Ingebrigtsen [this message]
2020-10-01  1:50                                   ` Lars Ingebrigtsen
2020-10-01 13:38                                   ` Thomas Plass
2020-10-01 16:19                                     ` Ulf Jasper
2020-10-01 16:22                                       ` Lars Ingebrigtsen
2020-10-01 16:54                                         ` Ulf Jasper
2020-10-01 16:59                                           ` Lars Ingebrigtsen
2020-10-01 18:40                                             ` Ulf Jasper
2020-10-01 18:47                                               ` Lars Ingebrigtsen
2020-10-01 19:00                                                 ` Ulf Jasper
2020-10-01 18:49                                           ` Thomas Plass
2020-10-01 18:53                                             ` Thomas Plass
2020-10-01 19:14                                             ` Ulf Jasper
2020-10-10 20:06                                               ` Lars Ingebrigtsen
2020-10-22 15:50                                                 ` Ulf Jasper
2021-05-11 14:10                                                   ` Lars Ingebrigtsen
2021-07-29 14:55                                                     ` Ulf Jasper
2021-07-30 11:37                                                       ` Lars Ingebrigtsen
2023-10-01  2:12                                                 ` Stefan Kangas
2023-10-12 14:49                                                   ` Ulf Jasper
2023-10-15 14:28                                                     ` Stefan Kangas
2023-10-19 14:11                                                       ` Ulf Jasper
2023-12-24 14:02                                                         ` Stefan Kangas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874knewwfc.fsf@gnus.org \
    --to=larsi@gnus.org \
    --cc=34315@debbugs.gnu.org \
    --cc=jan.tatarik@gmail.com \
    --cc=thunk2@arcor.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).