Function: icalendar-recur-tz-set-zone
icalendar-recur-tz-set-zone is a byte-compiled function defined in
icalendar-recur.el.gz.
Signature
(icalendar-recur-tz-set-zone DT VTIMEZONE &optional NONEXISTENT)
Documentation
Set the time zone offset and dst flag in DT based on VTIMEZONE.
DT should be an icalendar-date-time and VTIMEZONE should be an
icalendar-vtimezone. VTIMEZONE can also be an icalendar-utc-offset,
in which case this value is directly set in DT's zone field (without
changing its dst flag). The updated DT is returned.
This function generally sets only the zone and dst slots of DT, without
changing the other slots; its main purpose is to adjust date-times
generated from other date-times during recurrence rule calculations,
where a different time zone observance may be in effect in the original
date-time. It cannot be used to re-decode a fixed point in time into a
different time zone; for that, see icalendar-recur-tz-decode-time.
If given, NONEXISTENT is a keyword that specifies what to do if DT
represents a clock time that does not exist according to the relevant
observance in VTIMEZONE. The value :error means to signal an
'icalendar-tz-nonexistent-time error, and nil means to reset the
clock time in DT to an existing one; see
icalendar-recur-tz-observance-on.
Other relevant functions are documented in the icalendar group.
Shortdoc
;; icalendar
(icalendar-recur-tz-set-zone '(0 0 11 11 11 2024 1 -1 nil) vtimezone)
e.g. => (0 0 11 11 11 2024 1 nil 3600)
Source Code
;; Defined in /usr/src/emacs/lisp/calendar/icalendar-recur.el.gz
(defun icr:tz-set-zone (dt vtimezone &optional nonexistent)
"Set the time zone offset and dst flag in DT based on VTIMEZONE.
DT should be an `icalendar-date-time' and VTIMEZONE should be an
`icalendar-vtimezone'. VTIMEZONE can also be an `icalendar-utc-offset',
in which case this value is directly set in DT's zone field (without
changing its dst flag). The updated DT is returned.
This function generally sets only the zone and dst slots of DT, without
changing the other slots; its main purpose is to adjust date-times
generated from other date-times during recurrence rule calculations,
where a different time zone observance may be in effect in the original
date-time. It cannot be used to re-decode a fixed point in time into a
different time zone; for that, see `icalendar-recur-tz-decode-time'.
If given, NONEXISTENT is a keyword that specifies what to do if DT
represents a clock time that does not exist according to the relevant
observance in VTIMEZONE. The value :error means to signal an
\\='icalendar-tz-nonexistent-time error, and nil means to reset the
clock time in DT to an existing one; see
`icalendar-recur-tz-observance-on'."
(if (cl-typep vtimezone 'ical:utc-offset)
;; This is where the recurrence rule/time zone mutual dependence
;; bottoms out; don't remove this conditional!
(setf (decoded-time-zone dt) vtimezone)
;; Otherwise, if there's already zone information in dt, trust it
;; without looking up the observance. This is partly a performance
;; optimization (because the lookup is expensive) and partly about
;; avoiding problems: looking up the observance uses the clock time
;; in dt without considering the zone information, and doing this
;; when dt has already been adjusted to contain valid zone
;; information can invalidate that information.
;;
;; It's reliable to skip the lookup when dt already contains zone
;; information only because `icalendar-make-date-time',
;; `icalendar-date/time-add', and in particular
;; `icalendar-date-time-variant' are careful to remove the UTC
;; offset and DST information in the date-times they construct,
;; unless provided with enough information to fill those slots.
(unless (and (cl-typep dt 'ical:date-time)
(decoded-time-zone dt)
(booleanp (decoded-time-dst dt)))
;; This updates the relevant slots in dt as a side effect:
;; TODO: if no observance is found, is it ever sensible to signal an error,
;; instead of just leaving the zone slot unset?
(icr:tz-observance-on dt vtimezone t nonexistent)))
dt)