Subject: | today() fails when 00:00 is not valid in local time zone |
Some time zones, such as Brazil, do the daylight saving time shift at midnight, so 00:00::00 is not a valid time on the day that DST is entered. On these days, the first second of the day is 01:00:00.
Thus, when today() tries to truncate to the current day, it fails with the "Invalid local time for date in time zone" error message.
Equivalent code, using the day of the DST change time for Brazil:
$d = DateTime->new( year => 2014, month => 10, day => 19, time_zone => 'America/Sao_Paulo')
The documentation correctly notes that some times are invalid in some time zones, but having today() fail as well is somewhat unexpected. It can cause obscure failures for code that was running fine on any other day.
This is a tricky one. At minimum, this should be noted in the documentation.
One could argue that today() really means "the first valid moment of the given day", in which case the above example should return 2014-10-19T01:00:00. On the other hand, this may cause surprises for developers that assume that today() will always return a DateTime that's truncated to the day, with all smaller components set to zero.
Another exhausting alternative is to rework the whole DateTime system to allow for a "precision" for each DateTime, and consider all components smaller than the given precision to be undefined rather than zero. However, this is a large behavioral change to a key module, which would add to the trickiness.
I'm not sure what the best course is for this one...I ended up hacking a local safe_today() method that caught for the "Invalid local time" exception and moved the time one hour in the future.