After an upgrade to 6.0.2, TWiki doesn't work on Strawberry Perl (Windows):
configure
runs just fine, but each "normal" request fails with
POSIX::tzset not implemented on this architecture
. One impact is that I can't build a working
TWiki:Codev.TWikiPersonal
with 6.0.2 right now.
The problem has been introduced by fixing
Item7676:
TWiki::Time::formatTime() to observe outputTimeZone argument.
A
Perlmonks article
suggests using
Time::Piece::_tzset
, which came with Perl 5.12 and belongs to the core since then. If we want to continue support both Perl 5.10
and Strawberry Perl
and correct timezones, it seems that some ugliness can't be avoided.
--
TWiki:Main/HaraldJoerg
- 2015-12-07
How about using conditional code? You can test for
$TWiki::cfg{OS} eq 'WINDOWS'
, and call
Time::Piece::_tzset
, else call the POSIX version.
--
TWiki:Main.PeterThoeny
- 2015-12-10
Yes, that's one of the options, and probably an acceptable workaround. It isn't perfect, either:
- Conditional code is always smelly because you need to test all paths for code coverage. On the other hand, not testing on Windows wasn't perfect without conditional code right now.
- On Windows, Strawberry isn't the only Perl distribution. There are mixed reports about
POSIX::tzset
implementations in Activeperl. Future versions of Strawberry Perl might implement tzset
- who knows? I've considered wrapping the POSIX::tzset
call in try
and using Time::Piece::_tzset
in the catch
clause, which removes the assumption that "windows and only windows" is affected and will be affected for all times.
- It raises the minimum Perl version to 5.12 - for Windows. No big deal, in my opinion.
- Any solution based on environment variables isn't thread-safe. There are race conditions which cause the time zone for a process to be permanently changed, with appropriate confusion for future log entries of that process.
- Perl aficionados recommend using CPAN:DateTime
for time calculations because there are so many edge cases (Example: This year I missed one release meeting because Germany and USA both have DST, but they switch it off at different dates. I was one hour late.). I hesitate recommending that: The memory footprint is a high price for a maybe-not-so-important feature (and I love my tiny server, running on 512MB).
But within the small problem there's a bigger problem trying to get out.
The documentation of
TWiki::Time::formatTime
,
TWiki::Func::formatTime
, and the configuration variable
{DisplayTimeValues}
all restrict the permitted timezone values to
"gmtime"
and
"servertime"
, neither of which are actually
timezones. The old implementation had treated all "timezone" values different from
"gmtime"
as equivalent to
"servertime"
which is sloppy, based on the assumption that no other values are permitted anyway. In the current TWiki codebase, a few instances call
TWiki::Time::formatTime
, explicitly requiring
"servertime"
(most notably, the
SERVERTIME variable). But
"servertime"
is not a valid time zone, so in fact we are setting
$ENV{TZ}
to an invalid timezone value. This, according to the
tzset
system call, results in setting the timezone to UTC, which is exactly what the caller didn't request when he said
SERVERTIME
. Quoting
http://man7.org/linux/man-pages/man3/tzset.3.html
:
- If the TZ variable does not appear in the environment, the system timezone is used. The system timezone is configured by copying, or linking, a file in the tzfile(5) format to /etc/localtime. A timezone database of these files may be located in the system timezone directory (see the FILES section below).
- If the TZ variable does appear in the environment, but its value is empty, or cannot be interpreted using any of the formats specified below, then Coordinated Universal Time (UTC) is used.
It seems that in TWiki 6.0.2,
SERVERTIME is broken and the conditional code workaround wouldn't fix that.
By the way: It took me a while to figure out why TWiki on Windows breaks even if I set
{DisplayTimeValues} = 'gmtime'
. It is because
SERVERTIME
is explicitly used in
twiki.tmpl
. That could be changed, but on the other hand: For a personal installation,
SERVERTIME
is the (only) relevant time for the user.
As with so many time and date calculations: This needs some work to get it right.
--
TWiki:Main.HaraldJoerg
- 2015-12-11
As a workaround, I have simply wrapped the offending
tzset
calls in an
eval
block so that I can build
TWikiPersonal, which is needed to solve
Item7753, and opened a separate
Item7752 for the SERVERTIME stuff. Maybe we can just close this, and note that
TWiki::Time::formatTime()
doesn't support timezones on windows?
--
TWiki:Main.HaraldJoerg
- 2016-08-20
With the latest fixes by
TWiki:Main.HideyoImazu
for
Item7753, the issue is solved. The
eval
added by Rev. 30245 is somewhat smelly, but doesn't hurt - so I'd like to flag this one as "Waiting for Release".
--
TWiki:Main.HaraldJoerg
- 2017-09-04