emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] icalendar.el: Support timezones without DST


From: Sylvain Chouleur
Subject: [PATCH] icalendar.el: Support timezones without DST
Date: Sun, 09 Nov 2014 23:43:46 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Hi,

This patch is here to support vcalendar events which timezone doesn't
have daylight saving time.

I've faced this issue when receiving an event for which displayed
timezone was the sender's one, not mine.
The vcalendar event had DAYLIGHT and STANDARD timezones defined but the
timezones where equal.
The icalendar module couldn't decode the event yet because each timezone
event were missing RRULE value. This is allowed by RFC5545 :
https://tools.ietf.org/html/rfc5545#section-3.6.5

So what I do in this patch is: if RRULE is missing and OFFSETFROM ==
OFFSETTO, then we return a timezone composed only by "STD [+-]XX:XX"
without the recurrence rule part which is added only if OFFSETFROM !=
OFFSETTO

>From 69b73bf2f8d80ac656385e483bac02e904078d5d Mon Sep 17 00:00:00 2001
From: Sylvain Chouleur <address@hidden>
Date: Fri, 10 Oct 2014 00:05:42 +0200
Subject: [PATCH] * icalendar.el: Support timezones without DST

Some timezone does not define RRULE inside DAYLIGHT or STANDARD
components because they do not have a daylight saving time.
The RFC5545 specify that when no RRULE is specified, the observance is
effective just once.
The current icalendar code doesn't take care of the DTSTART so we can't
apply the RFC here but fortunately, when timezone do not use RRULE, the
TZOFFSETTO and TZOFFSETFROM values are always the same.

Signed-off-by: Sylvain Chouleur <address@hidden>
---
 ChangeLog                  |  5 +++++
 lisp/calendar/icalendar.el | 53 ++++++++++++++++++++++++----------------------
 2 files changed, 33 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cdc2a7bae785..4e12c2b1663e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-09  Sylvain Chouleur  <address@hidden>
+
+       * calendar/icalendar.el: Support timezone without daylight saving
+       time
+
 2014-11-08  Dani Moncayo  <address@hidden>
 
        * build-aux/msys-to-w32: simplify the initial over-engineered
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index 5f89318e139f..b024a38f8095 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -485,45 +485,48 @@ children."
 ALIST is an alist entry from a VTIMEZONE, like STANDARD.
 DST-P is non-nil if this is for daylight savings time.
 The strings are suitable for assembling into a TZ variable."
-  (let ((offset (car (cddr (assq 'TZOFFSETTO alist))))
-       (rrule-value (car (cddr (assq 'RRULE alist))))
-       (dtstart (car (cddr (assq 'DTSTART alist)))))
+  (let* ((offsetto (car (cddr (assq 'TZOFFSETTO alist))))
+        (offsetfrom (car (cddr (assq 'TZOFFSETFROM alist))))
+        (rrule-value (car (cddr (assq 'RRULE alist))))
+        (dtstart (car (cddr (assq 'DTSTART alist))))
+        (no-dst (equal offsetto offsetfrom)))
     ;; FIXME: for now we only handle RRULE and not RDATE here.
-    (when (and offset rrule-value dtstart)
+    (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 (and (string= freq "YEARLY") bymonth)
+       (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 offset 0) ?-) "+" "-")
-             (substring offset 1 3)
+             (if (eq (aref offsetto 0) ?-) "+" "-")
+             (substring offsetto 1 3)
              ":"
-             (substring offset 3 5))
+             (substring offsetto 3 5))
             ;; The start time.
-            (let* ((day (icalendar--get-weekday-number (substring byday -2)))
-                   (week (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
-              (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)))))))))
+            (unless no-dst
+              (let* ((day (icalendar--get-weekday-number (substring byday -2)))
+                     (week (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
+                (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))))))))))
 
 (defun icalendar--parse-vtimezone (alist)
   "Turn a VTIMEZONE ALIST into a cons (ID . TZ-STRING).
-- 
2.1.1

Regards
--
Sylvain

reply via email to

[Prev in Thread] Current Thread [Next in Thread]