[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: