Re: 780 files in /usr/share/zoneinfo/
On Tue 24 Nov 2020 at 13:07:10 (-0500), Greg Wooledge wrote:
> On Tue, Nov 24, 2020 at 04:45:53PM +0000, Curt wrote:
> > I have a problem:
> >
> > curty@einstein:~$ TZ=EST date
> > Tue Nov 24 11:43:42 EST 2020
> > curty@einstein:~$ TZ=PST date
> > Tue Nov 24 16:43:54 PST 2020
>
> As I said, figuring out the valid TZ strings for a given location on
> our planet is a challenge. Unfortunately, the ... fine people ... who
> devised the standards for this sort of thing thought it would be really
> super clever to treat ALL unknown TZ strings as if they were "UTC0".
>
> unicorn:~$ date -u ; TZ=UTC0 date ; TZ=Imaginary/Neverland date
> Tue Nov 24 17:54:28 UTC 2020
> Tue Nov 24 17:54:28 UTC 2020
> Tue Nov 24 17:54:28 Imaginary 2020
>
> TZ=PST is yet another unknown TZ string, so it's treated as "UTC0", or
> the Coordinated Universal Time zone, and you don't even get a WARNING
> that this is the case. It just silently gives you a wrong answer.
>
> I've been personally bitten by this, and it sucks. So much.
>
> unicorn:~$ TZ=PST date ; TZ=PST8PDT date ; TZ=America/Los_Angeles date
> Tue Nov 24 17:56:16 PST 2020
> Tue Nov 24 09:56:16 PST 2020
> Tue Nov 24 09:56:16 PST 2020
>
> To add insult to injury, the string that date(1) gives you as OUTPUT
> (in this case, "PST") is not accepted by the very same program as INPUT.
> In fact, I don't know of any way to get date(1) to give an output string
> that you can use as a valid TZ input string. You have to discover these
> values yourself, using out-of-band means.
>
> One of the ways to generate a valid TZ name, if your target happens to
> be in the United States, is to construct one of the old school Unix time
> zone names:
>
> EST5EDT
> CST6CDT
> MST7MDT
> PST8PDT
>
> If you can remember "Eastern Central Mountain Pacific", and if you can
> remember the numeric offset for any single one of them, then you can
> derive the full set.
>
> Another set of TZ labels that works for the USA is the transitional
> set that was popular 10-20 years ago:
>
> US/Eastern
> US/Central
> US/Mountain
> US/Pacific
>
> Those are even easier to derive than the "EST5EDT" style ones, albeit
> slightly more characters to type.
>
> Outside of the USA, you'll probably need to go with the "nearest big
> city" names that are the current vogue. The best way to use those is
> probably "ls /usr/share/zoneinfo", choose your continent, and then
> (for example) "ls /usr/share/zoneinfo/Asia". Then pick a city from
> the resulting set, and pray.
>
> If there's a better way, I don't know it.
I wrote this a while back; it probably needs another bout of tidying up.
$ type whattime
whattime is a function
whattime ()
{
[ -z "$1" ] && printf '%s\n' "Usage: ${FUNCNAME[0]} there [where]
prints the time in where or where/there or there/where.
Note that the result has to be Region/Place with a /." 1>&2 && return 1;
local Wherea="${1,,}" Whereb="${1,,}";
[ -n "$2" ] && Wherea="${1,,}/${2,,}" && Whereb="${2,,}/${1,,}";
local Unique1="$(mktemp "${Uniquetrash:-/tmp}/${FUNCNAME[0]}"-"$(date +%s)"-XXXX)";
local Unique2="$(mktemp "${Uniquetrash:-/tmp}/${FUNCNAME[0]}"-"$(date +%s)"-XXXX)";
( cd /usr/share/zoneinfo || return 9;
ls -1 */* >> "$Unique1";
grep -i -e "${Wherea// /_}" "$Unique1" >> "$Unique2";
grep -i -e "${Whereb// /_}" "$Unique1" >> "$Unique2";
local Nmatches="$(grep -e '/' "$Unique2" | LC_ALL=C sort -u | tee "$Unique1" | wc -l)";
[ "$Nmatches" = "1" ] && TZ=$(cat "$Unique1") && printf '%s ' "$TZ" && date '+%Y-%m-%d %T %z %A' )
}
$ whattime pari
Europe/Paris 2020-11-24 20:38:35 +0100 Tuesday
$
It should work on any single partial match, as demonstrated.
Of course, it helps to know the names of a few major cities.
Cheers,
David.
Reply to: