Branch: refs/heads/blead Home: https://github.com/Perl/perl5 Commit: 4c992435a2d3e98bba859d251e8869ac1f14a364 https://github.com/Perl/perl5/commit/4c992435a2d3e98bba859d251e8869ac1f14a364 Author: Karl Williamson <k...@cpan.org> Date: 2024-07-01 (Mon, 01 Jul 2024)
Changed paths: M ext/POSIX/POSIX.xs M ext/POSIX/lib/POSIX.pod M ext/POSIX/t/time.t M locale.c Log Message: ----------- Fix POSIX::strftime() This fixes GH #22351 The new sv_strftime_ints() API function acts consistently with regards to daylight savings time, with POSIX-mandated behavior, which takes the current locale into account. POSIX::strftime() is problematic in regard to this. This commit adds a backwards compatibility mode to preserve its behavior that inadvertently was changed by 86a9c18b6fab1949a26de790418b8b897a71e4ac. These functions are intended to wrap libc strftime(), including normalizing the input values. For example, if you pass 63 seconds as a value, they will typically change that to be 3 seconds into the next minute up. In C, the mktime() function is typically called first to do that normalization. (I don't know what happens if plain strftime() is called with unnormalized values.). mktime() looks at the current locale, determines if daylight savings time is in effect, and adjusts accordingly. Perl calls its own mktime-equivalent for you, eliminating the need for explicitly calling something that would need to always be called anyway, hence saving an extra step. mini_mktime() is the Perl mktime-equivalent. It is unaffected by locales, and does not consider the possibility of there being daylight savings time. The problem is that libc strftime() is affected by locale, and does consider dst. Perl uses these two functions together, and this inconsistency between them is bound to cause problems. The 'isdst' parameter to POSIX::strftime() is used to indicate if daylight savings is in effect for the time and date given by the other parameters. If perl used mktime() to normalize those values, it would calculate this for itself, using the passed-in value only as a hint. But since it uses mini_mktime(), it has to take that value as-is. Thus, daylight savings alone, out of all the input values, is not normalized. This is contrary to the documentation, and I didn't know this when I wrote the blamed commit. It turns out that typical uses of this function, like POSIX::strftime('%s', localtime) POSIX::strftime('%s', gmtime) cause the correct 'isdst' to be passed. But this is a defect in the interface that can bite you; changing it would cause cpan breakage. I wrote the API function sv_strftime_ints() to not have these issues. And, to workaround a defect in the POSIX definition of mktime(). It turns out you can't tell it you don't want to adjust for dayight time, except by changing the locale to one that doesn't have dst, such as the "C" locale. But this isn't a Perl-level function. To unsubscribe from these emails, change your notification settings at https://github.com/Perl/perl5/settings/notifications