jetmore / swaks

Swaks - Swiss Army Knife for SMTP
http://jetmore.org/john/code/swaks/
GNU General Public License v2.0
848 stars 86 forks source link

gets time wrong at the end of daylight savings #17

Closed ametzler closed 4 years ago

ametzler commented 4 years ago

Hello,

this is https://bugs.debian.org/955798 reported Russell Coker:

Swaks (oder the perl libraries it uses) does not get the start of DST right:

ametzler@argenau:~$ env LC_ALL=C TZ=Australia/Sydney faketime '2020-04-05 09:21:47'  date
Sun Apr  5 09:21:47 AEST 2020
ametzler@argenau:~$ env LC_ALL=C TZ=Australia/Sydney faketime '2020-04-05 09:21:47'  date +%z
+1000
ametzler@argenau:~$ env LC_ALL=C TZ=Australia/Sydney faketime '2020-04-05 12:59:58' swaks -s localhost -t [...]
[...]
 ~> Date: Sun, 05 Apr 2020 12:59:58 +1100
[...]
ametzler@argenau:~$ env LC_ALL=C TZ=Australia/Sydney faketime '2020-04-05 13:00:01' swaks -s localhost -t [...]
[...]
 ~> Date: Sun, 05 Apr 2020 13:00:01 +1000

The TZ offset in the date header jumps from +1100 to +1000 at about 13:00.

Russel describes the behavior as follows: Before 13:00 Swaks is taking the current human readable time but applying the timezone offset from yesterday when daylight savings was running. [...] It seems that swaks (or maybe the Perl libraries it uses) was about 10 or 11 hours late in recognising the daylight savings change. Maybe it thought that the early morning daylight savings time change meant early morning UTC not early morning in my timezone.

jetmore commented 4 years ago

This bug was actually a little stranger than reported. It actually got the DST change right once, then got it wrong for several hours:

for HOUR in `seq -w 0 23`
do
  env LC_ALL=C TZ=Australia/Sydney faketime "2020-04-05 $HOUR:30:00"  ../swaks -t foo --dump 2>&1 | grep Date:
done
Date: Sun, 05 Apr 2020 00:30:00 +1100
Date: Sun, 05 Apr 2020 01:30:00 +1100
Date: Sun, 05 Apr 2020 02:30:01 +1000   <------------
Date: Sun, 05 Apr 2020 03:30:00 +1100
Date: Sun, 05 Apr 2020 04:30:00 +1100
Date: Sun, 05 Apr 2020 05:30:00 +1100
Date: Sun, 05 Apr 2020 06:30:00 +1100
Date: Sun, 05 Apr 2020 07:30:00 +1100
Date: Sun, 05 Apr 2020 08:30:01 +1100
Date: Sun, 05 Apr 2020 09:30:00 +1100
Date: Sun, 05 Apr 2020 10:30:00 +1100
Date: Sun, 05 Apr 2020 11:30:00 +1100
Date: Sun, 05 Apr 2020 12:30:00 +1100
Date: Sun, 05 Apr 2020 13:30:00 +1000  <-------------
Date: Sun, 05 Apr 2020 14:30:01 +1000
Date: Sun, 05 Apr 2020 15:30:00 +1000
Date: Sun, 05 Apr 2020 16:30:00 +1000
Date: Sun, 05 Apr 2020 17:30:00 +1000
Date: Sun, 05 Apr 2020 18:30:00 +1000
Date: Sun, 05 Apr 2020 19:30:00 +1000
Date: Sun, 05 Apr 2020 20:30:01 +1000
Date: Sun, 05 Apr 2020 21:30:00 +1000
Date: Sun, 05 Apr 2020 22:30:00 +1000
Date: Sun, 05 Apr 2020 23:30:00 +1000

Unfortunately I'm pretty sure the issue is inside the Time::Local module or my use of it in a way I don't understand. Fortunately, 20 years later, I now recognize that my use of Time::Local was silly and I just replaced the whole thing with POSIX::strftime, which works a treat. Here's the new output:

for HOUR in `seq -w 0 23`
do
  env LC_ALL=C TZ=Australia/Sydney faketime "2020-04-05 $HOUR:30:00"  ../swaks -t foo --dump 2>&1 | grep Date:
done
Date: Sun, 05 Apr 2020 00:30:01 +1100
Date: Sun, 05 Apr 2020 01:30:00 +1100
Date: Sun, 05 Apr 2020 02:30:00 +1000
Date: Sun, 05 Apr 2020 03:30:00 +1000
Date: Sun, 05 Apr 2020 04:30:00 +1000
Date: Sun, 05 Apr 2020 05:30:00 +1000
Date: Sun, 05 Apr 2020 06:30:01 +1000
Date: Sun, 05 Apr 2020 07:30:00 +1000
Date: Sun, 05 Apr 2020 08:30:00 +1000
Date: Sun, 05 Apr 2020 09:30:00 +1000
Date: Sun, 05 Apr 2020 10:30:00 +1000
Date: Sun, 05 Apr 2020 11:30:01 +1000
Date: Sun, 05 Apr 2020 12:30:00 +1000
Date: Sun, 05 Apr 2020 13:30:00 +1000
Date: Sun, 05 Apr 2020 14:30:00 +1000
Date: Sun, 05 Apr 2020 15:30:00 +1000
Date: Sun, 05 Apr 2020 16:30:00 +1000
Date: Sun, 05 Apr 2020 17:30:01 +1000
Date: Sun, 05 Apr 2020 18:30:00 +1000
Date: Sun, 05 Apr 2020 19:30:00 +1000
Date: Sun, 05 Apr 2020 20:30:00 +1000
Date: Sun, 05 Apr 2020 21:30:00 +1000
Date: Sun, 05 Apr 2020 22:30:00 +1000
Date: Sun, 05 Apr 2020 23:30:01 +1000