From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Sylvain Chouleur Newsgroups: gmane.emacs.devel Subject: [PATCH] icalendar.el: Support timezones without DST Date: Sun, 09 Nov 2014 23:43:46 +0100 Message-ID: <87r3xcc7vh.fsf@nuada.dyved.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1415628150 29708 80.91.229.3 (10 Nov 2014 14:02:30 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 10 Nov 2014 14:02:30 +0000 (UTC) To: Emacs developers Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Nov 10 15:02:24 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XnpXu-00079B-DT for ged-emacs-devel@m.gmane.org; Mon, 10 Nov 2014 15:02:18 +0100 Original-Received: from localhost ([::1]:43361 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnpXu-0001Eg-2N for ged-emacs-devel@m.gmane.org; Mon, 10 Nov 2014 09:02:18 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnkBs-0005b3-GU for emacs-devel@gnu.org; Mon, 10 Nov 2014 03:19:17 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XnkBl-00006V-CW for emacs-devel@gnu.org; Mon, 10 Nov 2014 03:19:12 -0500 Original-Received: from 85-171-169-178.rev.numericable.fr ([85.171.169.178]:50666 helo=nuada.dyved.org) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XnkBl-00006B-1l for emacs-devel@gnu.org; Mon, 10 Nov 2014 03:19:05 -0500 Original-Received: from nuada.dyved.org (localhost [IPv6:::1]) by nuada.dyved.org (Postfix) with ESMTPS id 2DCF0480551 for ; Sun, 9 Nov 2014 23:43:47 +0100 (CET) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 85.171.169.178 X-Mailman-Approved-At: Mon, 10 Nov 2014 08:59:59 -0500 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:176682 Archived-At: --=-=-= Content-Type: text/plain 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 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-icalendar.el-Support-timezones-without-DST.patch >From 69b73bf2f8d80ac656385e483bac02e904078d5d Mon Sep 17 00:00:00 2001 From: Sylvain Chouleur 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 --- 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 + + * calendar/icalendar.el: Support timezone without daylight saving + time + 2014-11-08 Dani Moncayo * 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 --=-=-= Content-Type: text/plain Regards -- Sylvain --=-=-=--