diff options
| author | Eli Zaretskii | 2025-05-26 19:53:21 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2025-05-26 19:53:21 +0300 |
| commit | 3b5226af3f737c82f9bbedd8fbe067bab4b4b67a (patch) | |
| tree | 23706a4021735bea57c426b80982ed79652dc6a9 /src | |
| parent | 53371c959462a677a29ee869b3b6627facf3ed79 (diff) | |
| download | emacs-3b5226af3f737c82f9bbedd8fbe067bab4b4b67a.tar.gz emacs-3b5226af3f737c82f9bbedd8fbe067bab4b4b67a.zip | |
Fix DST time calculations on MS-Windows
* src/w32.c (w32_fix_tzset): New function.
* src/timefns.c (emacs_localtime_rz, tzlookup):
* src/w32.c (sys_localtime): Call 'w32_fix_tzset'.
(Bug#11281)
Diffstat (limited to 'src')
| -rw-r--r-- | src/timefns.c | 4 | ||||
| -rw-r--r-- | src/w32.c | 25 | ||||
| -rw-r--r-- | src/w32.h | 1 |
3 files changed, 30 insertions, 0 deletions
diff --git a/src/timefns.c b/src/timefns.c index 4d296ff8dcd..8cf424bbe7e 100644 --- a/src/timefns.c +++ b/src/timefns.c | |||
| @@ -189,6 +189,7 @@ emacs_localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) | |||
| 189 | display-time) are in real danger of missing timezone and DST | 189 | display-time) are in real danger of missing timezone and DST |
| 190 | changes. Calling tzset before each localtime call fixes that. */ | 190 | changes. Calling tzset before each localtime call fixes that. */ |
| 191 | tzset (); | 191 | tzset (); |
| 192 | w32_fix_tzset (); | ||
| 192 | #endif | 193 | #endif |
| 193 | tm = localtime_rz (tz, t, tm); | 194 | tm = localtime_rz (tz, t, tm); |
| 194 | if (!tm && errno == ENOMEM) | 195 | if (!tm && errno == ENOMEM) |
| @@ -306,6 +307,9 @@ tzlookup (Lisp_Object zone, bool settz) | |||
| 306 | block_input (); | 307 | block_input (); |
| 307 | emacs_setenv_TZ (zone_string); | 308 | emacs_setenv_TZ (zone_string); |
| 308 | tzset (); | 309 | tzset (); |
| 310 | #ifdef WINDOWSNT | ||
| 311 | w32_fix_tzset (); | ||
| 312 | #endif | ||
| 309 | timezone_t old_tz = local_tz; | 313 | timezone_t old_tz = local_tz; |
| 310 | local_tz = new_tz; | 314 | local_tz = new_tz; |
| 311 | tzfree (old_tz); | 315 | tzfree (old_tz); |
| @@ -10289,6 +10289,30 @@ w32_read_registry (HKEY rootkey, Lisp_Object lkey, Lisp_Object lname) | |||
| 10289 | } | 10289 | } |
| 10290 | 10290 | ||
| 10291 | 10291 | ||
| 10292 | /* mingw.org's MinGW doesn't declare _dstbias. MinGW64 defines it as a | ||
| 10293 | macro. */ | ||
| 10294 | #ifndef _dstbias | ||
| 10295 | __MINGW_IMPORT int _dstbias; | ||
| 10296 | #endif | ||
| 10297 | |||
| 10298 | /* Fix a bug in MS implementation of 'tzset'. This function should be | ||
| 10299 | called immediately after 'tzset'. */ | ||
| 10300 | void | ||
| 10301 | w32_fix_tzset (void) | ||
| 10302 | { | ||
| 10303 | char *tz_env = getenv ("TZ"); | ||
| 10304 | |||
| 10305 | /* When TZ is defined in the environment, '_tzset' updates _daylight, | ||
| 10306 | but not _dstbias. Then if we are switching from a timezone without | ||
| 10307 | DST to a timezone with DST, 'localtime' and friends will apply zero | ||
| 10308 | DST bias, which is incorrect. (When TZ is not defined, '_tzset' | ||
| 10309 | does update _dstbias using values obtained from Windows API | ||
| 10310 | GetTimeZoneInformation.) Here we fix that blunder by detecting | ||
| 10311 | this situation and forcing _dstbias to be 1 hour. */ | ||
| 10312 | if (tz_env && _daylight && !_dstbias) | ||
| 10313 | _dstbias = -3600; | ||
| 10314 | } | ||
| 10315 | |||
| 10292 | /* The Windows CRT functions are "optimized for speed", so they don't | 10316 | /* The Windows CRT functions are "optimized for speed", so they don't |
| 10293 | check for timezone and DST changes if they were last called less | 10317 | check for timezone and DST changes if they were last called less |
| 10294 | than 1 minute ago (see http://support.microsoft.com/kb/821231). So | 10318 | than 1 minute ago (see http://support.microsoft.com/kb/821231). So |
| @@ -10299,6 +10323,7 @@ struct tm * | |||
| 10299 | sys_localtime (const time_t *t) | 10323 | sys_localtime (const time_t *t) |
| 10300 | { | 10324 | { |
| 10301 | tzset (); | 10325 | tzset (); |
| 10326 | w32_fix_tzset (); | ||
| 10302 | return localtime (t); | 10327 | return localtime (t); |
| 10303 | } | 10328 | } |
| 10304 | 10329 | ||
| @@ -234,6 +234,7 @@ extern int openat (int, const char *, int, int); | |||
| 234 | extern int fchmodat (int, char const *, mode_t, int); | 234 | extern int fchmodat (int, char const *, mode_t, int); |
| 235 | extern int lchmod (char const *, mode_t); | 235 | extern int lchmod (char const *, mode_t); |
| 236 | extern bool symlinks_supported (const char *); | 236 | extern bool symlinks_supported (const char *); |
| 237 | extern void w32_fix_tzset (void); | ||
| 237 | 238 | ||
| 238 | 239 | ||
| 239 | /* Return total and free memory info. */ | 240 | /* Return total and free memory info. */ |