[tz] Bug report: "Asia" timezone
Zefram
zefram at fysh.org
Tue Jun 19 21:15:29 UTC 2012
Boruch Baum wrote:
>It's a double bug. It's printing out a
>non-existent timezone, and it's using GMT for
>"Asia"
It's well-known behaviour. It's part of libc, not date per se, as you
can see through (for example) ls's display of file timestamps:
$ TZ=UTC date; TZ=Europe/Paris date; TZ=Foo/Bar date
Tue Jun 19 21:04:33 UTC 2012
Tue Jun 19 23:04:33 CEST 2012
Tue Jun 19 21:04:33 Foo 2012
$ touch foo; TZ=UTC ls -l --full-time foo; TZ=Europe/Paris ls -l --full-time foo; TZ=Foo/Bar ls -l --full-time foo;
-rw-rw-r-- 1 zefram zefram 0 2012-06-19 21:04:43.105251376 +0000 foo
-rw-rw-r-- 1 zefram zefram 0 2012-06-19 23:04:43.105251376 +0200 foo
-rw-rw-r-- 1 zefram zefram 0 2012-06-19 21:04:43.105251376 +0000 foo
Finding that Foo/Bar or Asia/Moscow doesn't exist in the timezone
database, libc tries to interpret it as a POSIX timezone specification.
It's not actually well-formed as a POSIX timezone specification, but
it tries the best it can to interpret it anyway. In this case, the "/"
causes a parse error and so the specification is being truncated there.
(Some implementations don't truncate it, and you get the whole "Foo/Bar"
or whatever as the abbreviation in the date output.) The simplest form
of POSIX timezone specification consists of an abbreviation followed
by an offset; in this case the offset is missing, so libc is treating
it as a zero offset. The result is that "Foo/Bar" acts like the valid
POSIX timezone spec "Foo0", meaning a fixed offset of zero hours from
UT with abbreviation "Foo".
It would be better if libc could reject this $TZ value, rather than making
this futile attempt to make sense of it, but the historical API has very
little scope to signal errors, and backward compatibility is a bitch.
So you're stuck with this behaviour. Just learn the lesson from it:
don't make any new API or library be this forgiving with bad input.
-zefram
More information about the tz
mailing list