Subject: Re: bug#7337: 23.2; (require 'time) changes timezone

From: Stefan Monnier <[email-masked]>
Date: Mon, 08 Nov 2010 13:01:40 -0500

> Doing a (require 'time) changes the `current-time-zone' to the system
> default per a (set-time-zone-rule nil).  I think that loading a .el
> shouldn't change the zone.  The effect can be seen from "emacs -Q"

>     (let (before after)
>       (set-time-zone-rule "ABC+1")
>       (setq before (current-time-zone))
>       (require 'time)
>       (setq after  (current-time-zone))
>       (list (car before) (car after)))
>     => (-3600 39600)

> where I expected

>     => (-3600 -3600)

> which is what happens if evaluated a second time, since (require 'time)
> is then a no-op.

Indeed, that's a bug.

> I suppose it comes from display-time-world-list probing whether the
> Olson timezone names are known to the C library.  I think it should save
> and restore the existing TZ the way `add-change-log-entry' and
> `time-stamp-string' do.

But do those two other uses work?

> For some of my own code lately I tried a macro to hide the details and
> the unwind-protect a bit.  Perhaps a name like with-time-zone-rule or
> with-temporary-time-zone-rule would match set-time-zone-rule better than
> "...-TZ".

> (defmacro xtide-with-TZ (tz &rest body)
>   "Run BODY with `set-time-zone-rule' temporarily to TZ.
> The current timezone (per `getenv' \"TZ\") is restored by an
> `unwind-protect'."
>   (declare (indent 1))
>   `(let ((xtide-with-TZ--old (getenv "TZ")))
>      (set-time-zone-rule ,tz)
>      (unwind-protect
>          (progn ,@body)
>        (set-time-zone-rule xtide-with-TZ--old))))

And similar does this code work for you?  In my tests, (getenv "TZ")
just always returns nil.  So it seems we'd need to add a new function
time-zone-rule to get the current time-zone rule.  Or else we could
make set-time-zone-rule return the previous time-zone rule.

        Stefan