POSIX::Strftime Output Change In Perl V5.40 To V5.42

by Admin 53 views
Change in output of strftime from v5.40 to v5.42

Hey everyone,

There's been a reported issue regarding a change in the behavior of POSIX::strftime between Perl versions v5.40 and v5.42. This article dives into the details of this change, the steps to reproduce it, the expected behavior, and the commit that introduced the difference. Let's get started!

Module: POSIX

This issue specifically affects the POSIX module in Perl.

Description

It was reported on IRC by user sphex that there's an inconsistent output from POSIX::strftime when comparing Perl v5.40 and v5.42. The command that triggered this observation is:

TZ=Europe/Paris perl -E 'use POSIX "strftime"; say strftime("%FT%T%z", localtime 1761436800);'

The core of the issue is that the time zone offset generated by strftime differs between these two Perl versions for the same input time and time zone.

Steps to Reproduce

To reproduce this issue, you can run the following commands in your terminal. Make sure you have both Perl v5.40 and v5.42 installed to compare the outputs.

Perl 5.42:

perl -E 'BEGIN {$ENV{TZ}="Europe/Paris"} use POSIX "strftime"; say strftime("%FT%T%z", localtime 1761436800);'

This command outputs:

2025-10-26T02:00:00+0100

Perl 5.40:

perl -E 'BEGIN {$ENV{TZ}="Europe/Paris"} use POSIX "strftime"; say strftime("%FT%T%z", localtime 1761436800);'

This command outputs:

2025-10-26T02:00:00+0200

As you can see, the time zone offset differs: +0100 in v5.42 and +0200 in v5.40.

Expected Behavior

It's believed that the output from Perl v5.40, which is 2025-10-26T02:00:00+0200, is the correct output. This expectation is based on the understanding of how time zones and daylight saving time should be applied for the given timestamp and time zone.

To confirm this, a bisecting process was performed using the following command:

Porting/bisect.pl --start v5.40.0 --end v5.42.0 -e ' BEGIN {$ENV{TZ}="Europe/Paris"} use POSIX "strftime"; die "Wrong time" unless "2025-10-26T02:00:00+0200" eq strftime("%FT%T%z", localtime 1761436800);'

This command automates the process of checking out different commits between v5.40.0 and v5.42.0 and running the provided Perl code. It identifies the commit where the output deviates from the expected 2025-10-26T02:00:00+0200.

Culprit Commit

The bisecting process pinpointed the following commit as the culprit:

86a9c18b6fab1949a26de790418b8b897a71e4ac

This commit is the one that introduced the change in behavior. Further investigation into this commit's changes would be necessary to understand the root cause of the issue.

Perl Configuration

To provide a comprehensive understanding of the environment where this issue was observed, the Perl configuration is included below. This information can be crucial for debugging and identifying potential environmental factors that might influence the behavior.

Summary of my perl5 (revision 5 version 42 subversion 0) configuration:

 Platform:
 osname=linux
 osvers=6.12.22+bpo-amd64
 archname=x86_64-linux
 uname='linux simcop2387.info 6.12.22+bpo-amd64 #1 smp preempt_dynamic debian 6.12.22-1~bpo12+1 (2025-04-25) x86_64 gnulinux '
 config_args='-Dprefix=/home/perlbot/perl5/custom/5.42.0 -de -Dusedevel -Duseshrplib -Dusemymalloc=y -Accflags=-fpie -fPIC -mtune=native -fstack-protector-all -pie -D_FORTIFY_SOURCE=2 -ggdb -DPERL_EMERGENCY_SBRK -Aldflags=-Wl,-z,now -Wl,-zrelro -Wl,-z,noexecstack -A'eval:scriptdir=/home/perlbot/perl5/custom/5.42.0/bin''
 hint=recommended
 useposix=true
 d_sigaction=define
 useithreads=undef
 usemultiplicity=undef
 use64bitint=define
 use64bitall=define
 uselongdouble=undef
 usemymalloc=y
 default_inc_excludes_dot=define

 Compiler:
 cc='cc'
 ccflags ='-fpie -fPIC -mtune=native -fstack-protector-all -pie -D_FORTIFY_SOURCE=2 -ggdb -DPERL_EMERGENCY_SBRK -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
 optimize='-O2'
 cppflags='-fpie -fPIC -mtune=native -fstack-protector-all -pie -D_FORTIFY_SOURCE=2 -ggdb -DPERL_EMERGENCY_SBRK -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
 ccversion=''
 gccversion='12.2.0'
 gccosandvers=''
 intsize=4
 longsize=8
 ptrsize=8
 doublesize=8
 byteorder=12345678
 doublekind=3
 d_longlong=define
 longlongsize=8
 d_longdbl=define
 longdblsize=16
 longdblkind=3
 ivtype='long'
 ivsize=8
 nvtype='double'
 nvsize=8
 Off_t='off_t'
 lseeksize=8
 alignbytes=8
 prototype=define
 Linker and Libraries:
 ld='cc'
 ldflags =' -Wl,-z,now -Wl,-zrelro -Wl,-z,noexecstack -fstack-protector-strong -L/usr/local/lib'
 libpth=/usr/local/lib /usr/lib/x86_64-linux-gnu /usr/lib /usr/lib64
 libs=-lpthread -ldl -lm -lcrypt -lutil -lc
 perllibs=-lpthread -ldl -lm -lcrypt -lutil -lc
 libc=/lib/x86_64-linux-gnu/libc.so.6
 so=so
 useshrplib=true
 libperl=libperl.so
 gnulibc_version='2.36'
 Dynamic Linking:
 dlsrc=dl_dlopen.xs
 dlext=so
 d_dlsymun=undef
 ccdlflags='-Wl,-E -Wl,-rpath,/home/perlbot/perl5/custom/5.42.0/lib/5.42.0/x86_64-linux/CORE'
 cccdlflags='-fPIC'
 lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'

Characteristics of this binary (from libperl): 
 Compile-time options:
 HAS_LONG_DOUBLE
 HAS_STRTOLD
 HAS_TIMES
 MYMALLOC
 PERLIO_LAYERS
 PERL_COPY_ON_WRITE
 PERL_DONT_CREATE_GVSV
 PERL_HASH_FUNC_SIPHASH13
 PERL_HASH_USE_SBOX32
 PERL_MALLOC_WRAP
 PERL_OP_PARENT
 PERL_PRESERVE_IVUV
 PERL_USE_DEVEL
 PERL_USE_SAFE_PUTENV
 USE_64_BIT_ALL
 USE_64_BIT_INT
 USE_LARGE_FILES
 USE_LOCALE
 USE_LOCALE_COLLATE
 USE_LOCALE_CTYPE
 USE_LOCALE_NUMERIC
 USE_LOCALE_TIME
 USE_PERLIO
 USE_PERL_ATOF
 Built under linux
 Compiled at Jul 3 2025 21:14:07
 %ENV:
 PERLBREW_HOME="/home/perlbot/.perlbrew"
 PERLBREW_MANPATH="/home/perlbot/perl5/perlbrew/perls/perlbot-main/man"
 PERLBREW_PATH="/home/perlbot/perl5/perlbrew/bin:/home/perlbot/perl5/perlbrew/perls/perlbot-main/bin"
 PERLBREW_PERL="perlbot-main"
 PERLBREW_ROOT="/home/perlbot/perl5/perlbrew"
 PERLBREW_SHELLRC_VERSION="0.86"
 PERLBREW_VERSION="0.86"
 @INC:
 /home/perlbot/perl5/custom/5.42.0/lib/site_perl/5.42.0/x86_64-linux
 /home/perlbot/perl5/custom/5.42.0/lib/site_perl/5.42.0
 /home/perlbot/perl5/custom/5.42.0/lib/5.42.0/x86_64-linux
 /home/perlbot/perl5/custom/5.42.0/lib/5.42.0

The Perl configuration details provide insights into the environment in which the issue was reproduced. Key aspects include the operating system (Linux), Perl version (5.42.0), compiler (gcc 12.2.0), and various compile-time options. This information is crucial for anyone attempting to debug or fix the issue, as it helps to ensure that the problem can be reproduced in a similar environment.

Summary and Next Steps

In summary, a change in the output of POSIX::strftime has been observed between Perl v5.40 and v5.42 when formatting a specific time with the Europe/Paris time zone. The commit 86a9c18b6fab1949a26de790418b8b897a71e4ac has been identified as the cause of this change.

Next steps would involve:

  1. Deep Dive into the Culprit Commit: Analyzing the changes introduced by commit 86a9c18b6fab1949a26de790418b8b897a71e4ac to understand how it affected the POSIX::strftime function.
  2. Identify the Root Cause: Determining why the changes in the commit led to the incorrect time zone offset.
  3. Develop a Fix: Implementing a solution that restores the correct behavior of strftime without introducing new issues.
  4. Testing: Thoroughly testing the fix to ensure it resolves the problem and doesn't negatively impact other functionality.

This issue highlights the importance of careful change management and thorough testing when updating software, especially in areas that deal with time and date manipulations, which can be complex and prone to subtle errors.

If you're experiencing this issue or have insights into the cause, feel free to share your thoughts and findings. Let's work together to get this resolved!