Subject: Re: bug#11281: DST has not effect on windows XP when system DST adjustment is disabled

From: Kazuhiro Ito <[email-masked]>
Date: Sat, 24 May 2025 13:32:54 +0900

> > > (let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
> > >   (setenv "TZ" nil)
> > >   (decode-time time "est5edt"))
> > > 
> > > Expected result: (0 0 8 20 5 2025 2 t -14400)
> > > Actual result:   (0 0 7 20 5 2025 2 t -18000)
> > > 
> > > As far as I tested, the result depends on whether DST is enabled in
> > > the Windows Control Panel at the time of evaluating `(setenv "TZ"
> > > nil)'.  In the case of Windows timezone which doesn't have DST, the
> > > result is the same with unchecking DST option.
> > 
> > I think this is because MSVCRT routines assume that every time zone
> > has DST and changes to and from DST on certain fixed dates.  IOW, they
> > don't support timezones without DST and don't access the Windows
> > settings for the actual timezone you are using.  So the conversion to
> > EST5EDT is performed as if your timezone also had DST and the DST were
> > in effect at that date.
> 
> Note that this:
> 
>   (let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
>     (setenv "TZ" "JST-9")
>     (decode-time time "est5edt"))
> 
> yields the expected result.

Yes, but it is true only if you had never called `(setenv "TZ" nil)'.
Your example yields unexpected result if TZ environmental variable is
not set at starting emacs (and it is Windows's default).  Probably you
set TZ environmental variable.

;; After setting timezone without DST in the Windows Control Panel
$ TZ= emacs -Q

(let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
  (setenv "TZ" "JST-9")
  (decode-time time "est5edt"))

-> unexpected result

So, following code would fail too.

(let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
  ;; After setting timezone without DST in the Windows Control Panel
  (setenv "TZ" nil)
  (setenv "TZ" "JST-9")
  (decode-time time "est5edt"))

-> unexpected result

> That is, as long as you tell MSVCRT that
> your current timezone doesn't use DST, the conversion is correct.

As I wrote above, this problem occurs after you once call `(setenv
"TZ" nil)' under setting that system timezone is non-DST
timezone.  If you don't set TZ to nil, conversion would always
succeed.

$ TZ=est5edt emacs -Q

(let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
  (setenv "TZ" "JST-9t")
  (decode-time time "est5edt"))

-> expected result

(let ((time (encode-time '(0 0 12 20 5 2025 nil nil t))))
  (setenv "TZ" "pst8pdt")
  (decode-time time "est5edt"))

-> expected result

-- 
Kazuhiro Ito