3 # Copyright 2005 Sun Microsystems, Inc. All rights reserved.
4 # Use is subject to license terms.
6 # ident "%Z%%M% %I% %E% SMI"
8 # '@(#)tzselect.ksh 1.8'
10 # Ask the user about the time zone, and output the resulting TZ value to stdout.
11 # Interact with the user via stderr and stdin.
13 # Contributed by Paul Eggert
17 # This script requires several features of the Korn shell.
18 # If your host lacks the Korn shell,
19 # you can use either of the following free programs instead:
21 # <a href=ftp://ftp.gnu.org/pub/gnu/>
22 # Bourne-Again shell (bash)
25 # <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
29 # This script also uses several features of modern awk programs.
30 # If your host lacks awk, or has an old awk that does not conform to POSIX.2,
31 # you can use either of the following free programs instead:
33 # <a href=ftp://ftp.gnu.org/pub/gnu/>
37 # <a href=ftp://ftp.whidbey.net/pub/brennan/>
44 LOCALE
=/usr
/bin
/locale
46 PRINTF
=/usr
/bin
/printf
48 GETTEXT
=/usr
/bin
/gettext
50 TZDIR
=/usr
/share
/lib
/zoneinfo
53 ERR_NO_SETUP
="%s: time zone files are not set up correctly"
54 INFO_LOCATION
="Please identify a location so that time zone rules \
55 can be set correctly."
56 INFO_SELECT_CONT
="Please select a continent or ocean."
57 INFO_POSIX
="none - I want to specify the time zone using the POSIX \
59 WARN_ENTER_NUM
="Please enter a number in range."
60 INFO_ENTER_POSIX
="Please enter the desired value of the TZ environment \
62 INFO_POSIX_EX
="For example, GST-10 is a zone named GST that is 10 hours \
64 ERR_INV_POSIX
="\`%s\' is not a conforming POSIX time zone string."
65 INFO_SELECT_CNTRY
="Please select a country or region."
66 INFO_SELECT_TZ
="Please select one of the following time zone regions."
67 INFO_EXTRA1
="Local time is now: %s"
68 INFO_EXTRA2
="Universal Time is now: %s"
69 INFO_INFO
="The following information has been given:"
70 INFO_TZ
="Therefore TZ='%s' will be used."
71 INFO_OK
="Is the above information OK?"
74 WARN_ENTER_YORN
="Please enter 1 for Yes, or 2 for No."
75 INFO_FINE
="Here is the TZ value again, this time on standard output:"
78 TEXTDOMAINDIR
=/usr
/lib
/locale
; export TEXTDOMAINDIR
79 TEXTDOMAIN
=SUNW_OST_OSCMD
; export TEXTDOMAIN
80 DOMAIN2
=SUNW_OST_ZONEINFO
82 # Make sure the tables are readable.
83 TZ_COUNTRY_TABLE
=$TZDIR/tab
/country.tab
84 TZ_ZONE_TABLE
=$TZDIR/tab
/zone_sun.tab
85 for f
in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
88 $PRINTF >&2 "`$GETTEXT "$ERR_NO_SETUP"`\n" $0
97 # For C locale, don't need to call gettext(1)
98 loc_messages
=`$LOCALE | $GREP LC_MESSAGES | $AWK -F"=" '{print $2}`
99 if [ "$loc_messages" = "\"C\"" -o "$loc_messages" = "C" ]; then
105 iafrica
=`$GETTEXT $DOMAIN2 Africa`
106 iamerica
=`$GETTEXT $DOMAIN2 Americas`
107 iantarctica
=`$GETTEXT $DOMAIN2 Antarctica`
108 iarcticocean
=`$GETTEXT $DOMAIN2 "Arctic Ocean"`
109 iasia
=`$GETTEXT $DOMAIN2 Asia`
110 iatlanticocean
=`$GETTEXT $DOMAIN2 "Atlantic Ocean"`
111 iaustralia
=`$GETTEXT $DOMAIN2 Australia`
112 ieurope
=`$GETTEXT $DOMAIN2 Europe`
113 ipacificocean
=`$GETTEXT $DOMAIN2 "Pacific Ocean"`
114 iindianocean
=`$GETTEXT $DOMAIN2 "Indian Ocean"`
115 none
=`$GETTEXT "$INFO_POSIX"`
117 # Begin the main loop. We come back here if the user wants to retry.
119 $PRINTF >&2 "`$GETTEXT "$INFO_LOCATION"`\n"
125 # Ask the user for continent or ocean.
126 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_CONT"`\n"
128 select continent
in \
144 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n";;
148 $iafrica) continent
=Africa
;;
149 $iamerica) continent
=America
;;
150 $iantarctica) continent
=Antarctica
;;
151 $iarcticocean) continent
=Arctic
;;
152 $iasia) continent
=Asia
;;
153 $iatlanticocean) continent
=Atlantic
;;
154 $iaustralia) continent
=Australia
;;
155 $ieurope) continent
=Europe
;;
156 $iindianocean) continent
=Indian
;;
157 $ipacificocean) continent
=Pacific
;;
158 $none) continent
=none
;;
167 # Ask the user for a POSIX TZ string. Check that it conforms.
169 $PRINTF >&2 "`$GETTEXT "$INFO_ENTER_POSIX"`\n"
170 $PRINTF >&2 "`$GETTEXT "$INFO_POSIX_EX"`\n"
173 env LC_ALL
=C
$AWK -v TZ
="$TZ" 'BEGIN {
174 tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
175 time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
176 offset = "[-+]?" time
177 date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
178 datetime = "," date "(/" time ")?"
179 tzpattern = "^(:.*|" tzname offset "(" tzname \
180 "(" offset ")?(" datetime datetime ")?)?)$"
181 if (TZ ~ tzpattern) exit 1
185 $PRINTF >&2 "`$GETTEXT "$ERR_INV_POSIX"`\n" $TZ
190 # Get list of names of countries in the continent or ocean.
191 countries
=$
($AWK -F'\t' \
192 -v continent
="$continent" \
193 -v TZ_COUNTRY_TABLE
="$TZ_COUNTRY_TABLE" \
196 $3 ~ ("^" continent "/") {
197 if (!cc_seen[$1]++) cc_list[++ccs] = $1
200 while (getline <TZ_COUNTRY_TABLE) {
201 if ($0 !~ /^#/) cc_name[$1] = $2
203 for (i = 1; i <= ccs; i++) {
205 if (cc_name[country]) {
206 country = cc_name[country]
211 ' <$TZ_ZONE_TABLE |
$SORT -f)
216 for country
in $countries
218 if [ $is_C -eq 1 ]; then
221 icountry
[c
]=`${GETTEXT} ${DOMAIN2} $country`
223 ocountry
[c
]="$country"
228 # If there's more than one country, ask the user which one.
231 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_CNTRY"`\n"
232 select xcountry
in ${icountry[*]}
236 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n"
240 if [ "$xcountry" = "${icountry[$c]}" ];
242 country
="${ocountry[$c]}"
245 if [ $c -lt $maxnum ]; then
264 # Get list of names of time zone rule regions in the country.
265 regions
=$
($AWK -F'\t' \
266 -v country
="$country" \
267 -v TZ_COUNTRY_TABLE
="$TZ_COUNTRY_TABLE" \
271 while (getline <TZ_COUNTRY_TABLE) {
272 if ($0 !~ /^#/ && country == $2) {
278 $1 == cc { print $5 }
284 for region
in $regions
286 if [ $is_C -eq 1 ]; then
289 iregion
[c
]=`${GETTEXT} ${DOMAIN2} $region`
296 # If there's more than one region, ask the user which one.
299 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_TZ"`\n"
301 select xregion
in ${iregion[*]}
305 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n"
309 if [ "$xregion" = "${iregion[$c]}" ];
311 region
="${oregion[$c]}"
314 if [ $c -lt $maxnum ]; then
332 # Determine TZ from country and region.
334 -v country
="$country" \
335 -v region
="$region" \
336 -v TZ_COUNTRY_TABLE
="$TZ_COUNTRY_TABLE" \
340 while (getline <TZ_COUNTRY_TABLE) {
341 if ($0 !~ /^#/ && country == $2) {
348 $1 == cc && $5 == region {
349 # Check if tzname mapped to
350 # backward compatible tzname
359 # Make sure the corresponding zoneinfo file exists.
360 TZ_for_date
=$TZDIR/$TZ
362 $PRINTF >&2 "`$GETTEXT "$ERR_NO_SETUP"`\n" $0
365 # Absolute path TZ's not supported
370 # Use the proposed TZ to output the current date relative to UTC.
371 # Loop until they agree in seconds.
372 # Give up after 8 unsuccessful tries.
376 for i
in 1 2 3 4 5 6 7 8
378 TZdate
=$
(LANG
=C TZ
="$TZ_for_date" $DATE)
379 UTdate
=$
(LANG
=C TZ
=UTC0
$DATE)
380 TZsec
=$
($EXPR "$TZdate" : '.*:\([0-5][0-9]\)')
381 UTsec
=$
($EXPR "$UTdate" : '.*:\([0-5][0-9]\)')
384 extra_info1
=$
($PRINTF "`$GETTEXT "$INFO_EXTRA1"`" \
386 extra_info2
=$
($PRINTF "`$GETTEXT "$INFO_EXTRA2"`" \
393 # Output TZ info and ask the user to confirm.
396 $PRINTF >&2 "`$GETTEXT "$INFO_INFO"`\n"
399 case $country+$region in
400 ?
*+?
*) $PRINTF >&2 " $xcountry$newline $xregion\n";;
401 ?
*+) $PRINTF >&2 " $xcountry\n";;
402 +) $PRINTF >&2 " TZ='$TZ'\n"
405 $PRINTF >&2 "`$GETTEXT "$INFO_TZ"`\n" "$TZ"
406 $PRINTF >&2 "$extra_info1\n"
407 $PRINTF >&2 "$extra_info2\n"
408 $PRINTF >&2 "`$GETTEXT "$INFO_OK"`\n"
411 # select ok in Yes No
412 Yes
="`$GETTEXT "$INFO_YES"`"
413 No
="`$GETTEXT "$INFO_NO"`"
414 select ok
in $Yes $No
418 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_YORN"`\n"
430 $PRINTF >&2 "`$GETTEXT "$INFO_FINE"`\n"