On Saturday 22 November 2025 20:34:06 LIU Hao wrote:
> 在 2025-11-22 09:24, Pali Rohár 写道:
> > I'm somehow not able to trigger this issue.
> > 
> > On 64-bit Windows 10 system I'm always getting this line which does not
> > trigger Assertion failed:
> > 
> > pacific _localtime32(1112524200): sec=0 min=30 hour=3 mday=3 mon=3 year=105 
> > wday=0 yday=92 isdst=1
> > 
> > This output is from 32-bit crtdll, msvcrt, ucrt and 64-bit msvcrt and ucrt 
> > builds.
> > 
> > I also tested it on the clean evaluation Windows Server 2022
> > installation and the output is same, the test is passing.
> > 
> > Any idea what I could have missed?
> 
> This issue can be reproduced with UCRT, so I can build it in Visual Studio,
> linking against Microsoft debug CRT, and step into UCRT sources.
> 
> In C:\Program Files (x86)\Windows Kits\10\Source\10.0.26100.0\ucrt\time 
> there's:
> 
>    int  daylight = 0;
>    long dstbias  = 0;
>    long timezone = 0;
>    _ERRCHECK(_get_daylight(&daylight));
>    _ERRCHECK(_get_dstbias (&dstbias ));   // <<==== gets DST bias into 
> `dstbias`
>    _ERRCHECK(_get_timezone(&timezone));
> 
> The offending invocation to `_localtime32()`, which reaches here indirectly,
> receives a value of 0 in `dstbias`. It should be -3600.
> 
> 
> And here's its implementation:
> 
>    extern "C" errno_t __cdecl _get_dstbias(long* result)
>    {
>        _VALIDATE_RETURN_ERRCODE(result != nullptr, EINVAL);
> 
>        // This variable is correctly inited at startup, so no need to check if
>        // CRT init finished.
>        *result = _dstbias.value();
>        return 0;
>    }
> 
> This comment is incorrect. It seems that the value is not initialized at
> startup, but by the first call to `_localtime32()`. If all those calls to
> `_localtime32()` and `_localtime64()` before the loop are removed, the
> assertion will pass.
> 
> This might explain why it doesn't fail on your side; maybe you are in that
> time zone, but otoh I'm not (we don't do DST whatsoever).
> 
> 
> And the fact that `_dstbias` is a static object probably means that it's
> impossible to change the time zone with `putenv("TZ=PST8PDT"); tzset();`
> once a TZ-aware function has been called.
> 
> So the test could be split into three files.
> 
> 
> -- 
> Best regards,
> LIU Hao

Thank you for debugging this. Now I think I see where is the bug.
The hint with (system) timezone which does not have DST active helped
there.

If I unset "Automatically adjust clock for daylight saving changes"
option in Windows Date and Time system dialog then the test starts failing.

I played a bit with it and seems that the default _dstbias variable has
value -3600. And first usage of mktime/localtime reinitialize timezone
from TZ variable.

But It looks like that _dstbias variable is changed only when changing
timezone to the system one, and in this case it is set to the system tz
dst bias value. When changing timezone to the non-system timezone
(e.g. TZ=PST8PDT) then the _dstbias variable is unchanged.

At the beginning of the test is used system timezone as TZ env is not
set (which initialize _dstbias variable to the system value), then there
is a switch to TZ=PST8PDT (which does not touch _dstbias variable) and
so pacific tests starts failing if the system tz dst bias is not same as
for PST8PDT zone.

For me it looks like a bug that _tzset does not change _dstbias to -3600
when env TZ=PST8PDT is set, but rather let _dstbias to the old value.

Simple test case:

  #include <stdio.h>
  #include <time.h>

  int main() {

    printf("_dstbias=%ld\n", _dstbias);

    printf("_tzset()\n");
    _tzset();

    printf("_dstbias=%ld\n", _dstbias);

    printf("_putvenv(\"TZ=PST8PDT\")\n");
    _putenv("TZ=PST8PDT");

    printf("_tzset()\n");
    _tzset();

    printf("_dstbias=%ld\n", _dstbias);

    return 0;

  }

With "Automatically adjust clock for daylight saving changes" option
enabled in system settings it prints:

  _dstbias=-3600
  _tzset()
  _dstbias=-3600
  _putvenv("TZ=PST8PDT")
  _tzset()
  _dstbias=-3600

And when that option is unchecked it prints:

  _dstbias=-3600
  _tzset()
  _dstbias=0
  _putvenv("TZ=PST8PDT")
  _tzset()
  _dstbias=0

If you think that this is a bug, could somebody with ms account report
this UCRT issue?


For our test case, I think that it splitting it into 3 different files
and executables does not help. When using the PST8PDT timezone in the
test we need to explicitly set _dstbias variable to -3600 after _tzset()
call, as msvcrt and UCRT does not do it for us.


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to