From 69b69306097b561b9c2c7dfeafd4aaff460b6fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Sat, 20 Apr 2019 22:39:44 +0200 Subject: Add timezone handling. This is a way to large commit. But I see no feasable way to break it down into multiple smaller commits. The main "secret" to solving timezones for recurring events was to remember to recalculate timezones whenever a new instance of the object was generated. This current implementation seems really slow (> 1s). Further testing is needed. --- module/vcalendar.scm | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'module/vcalendar.scm') diff --git a/module/vcalendar.scm b/module/vcalendar.scm index 2b664b56..a45e54a2 100644 --- a/module/vcalendar.scm +++ b/module/vcalendar.scm @@ -6,6 +6,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-19) #:use-module (srfi srfi-19 util) + #:use-module (srfi srfi-19 setters) #:use-module (srfi srfi-26) #:use-module ((ice-9 optargs) #:select (define*-public)) #:use-module (util) @@ -23,28 +24,23 @@ (define (parse-dates! cal) "Parse all start times into scheme date objects." - (for-each-in (children cal 'VTIMEZONE) - (lambda (tz) - (for-each (lambda (p) (mod! (attr p "DTSTART") string->time-utc)) - (children tz)) - - ;; TZSET is the generated recurrence set of a timezone - (set! (attr tz 'X-HNH-TZSET) - (make-tz-set tz)))) - - (for-each - (lambda (ev) - (mod! (attr ev "DTSTART") string->time-utc - (attr ev "DTEND") string->time-utc) - - (when (prop (attr* ev 'DTSTART) 'TZID) - (let* ((of (get-tz-offset ev))) - (set! (prop (attr* ev 'DTSTART) 'TZID) #f) - ;; 5545 says that DTEND is local time iff DTSTART is local time. - ;; But who says that will be true... - (mod! (attr ev 'DTSTART) - (cut subtract-duration <> (make-duration of)))))) - (children cal 'VEVENT)) + (for tz in (children cal 'VTIMEZONE) + (for-each (lambda (p) (mod! (attr p "DTSTART") string->time-utc)) + (children tz)) + + ;; TZSET is the generated recurrence set of a timezone + (set! (attr tz 'X-HNH-TZSET) + (make-tz-set tz))) + + (for ev in (children cal 'VEVENT) + (define date (parse-datetime (attr ev 'DTSTART))) + + (mod! (attr ev "DTEND") string->time-utc) + (set! (attr ev "DTSTART") (date->time-utc date)) + + (when (prop (attr* ev 'DTSTART) 'TZID) + (set! (zone-offset date) (get-tz-offset ev) + (attr ev 'DTSTART) (date->time-utc date)))) ;; Return cal) -- cgit v1.2.3