2 |
|
|
3 |
|
PKGVERSION='(tzcode) ' |
4 |
|
TZVERSION=see_Makefile |
5 |
+ |
REPORT_BUGS_TO=tz@iana.org |
6 |
|
|
7 |
|
# Ask the user about the time zone, and output the resulting TZ value to stdout. |
8 |
|
# Interact with the user via stderr and stdin. |
9 |
|
|
10 |
< |
# Contributed by Paul Eggert. |
10 |
> |
# Contributed by Paul Eggert. This file is in the public domain. |
11 |
|
|
12 |
|
# Porting notes: |
13 |
|
# |
14 |
< |
# This script requires a Posix-like shell with the extension of a |
14 |
> |
# This script requires a Posix-like shell and prefers the extension of a |
15 |
|
# 'select' statement. The 'select' statement was introduced in the |
16 |
|
# Korn shell and is available in Bash and other shell implementations. |
17 |
|
# If your host lacks both Bash and the Korn shell, you can get their |
21 |
|
# Korn Shell <http://www.kornshell.com/> |
22 |
|
# Public Domain Korn Shell <http://www.cs.mun.ca/~michael/pdksh/> |
23 |
|
# |
24 |
+ |
# For portability to Solaris 9 /bin/sh this script avoids some POSIX |
25 |
+ |
# features and common extensions, such as $(...) (which works sometimes |
26 |
+ |
# but not others), $((...)), and $10. |
27 |
+ |
# |
28 |
|
# This script also uses several features of modern awk programs. |
29 |
|
# If your host lacks awk, or has an old awk that does not conform to Posix, |
30 |
|
# you can use either of the following free programs instead: |
35 |
|
|
36 |
|
# Specify default values for environment variables if they are unset. |
37 |
|
: ${AWK=awk} |
38 |
< |
: ${TZDIR=$(pwd)} |
38 |
> |
: ${TZDIR=`pwd`} |
39 |
|
|
40 |
+ |
# Output one argument as-is to standard output. |
41 |
+ |
# Safer than 'echo', which can mishandle '\' or leading '-'. |
42 |
+ |
say() { |
43 |
+ |
printf '%s\n' "$1" |
44 |
+ |
} |
45 |
+ |
|
46 |
|
# Check for awk Posix compliance. |
47 |
|
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1 |
48 |
|
[ $? = 123 ] || { |
49 |
< |
echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible." |
49 |
> |
say >&2 "$0: Sorry, your '$AWK' program is not Posix compatible." |
50 |
|
exit 1 |
51 |
|
} |
52 |
|
|
53 |
< |
if [ "$1" = "--help" ]; then |
54 |
< |
cat <<EOF |
55 |
< |
Usage: tzselect |
53 |
> |
coord= |
54 |
> |
location_limit=10 |
55 |
> |
zonetabtype=zone1970 |
56 |
> |
|
57 |
> |
usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT] |
58 |
|
Select a time zone interactively. |
59 |
|
|
60 |
< |
Report bugs to tz@iana.org. |
61 |
< |
EOF |
62 |
< |
exit |
63 |
< |
elif [ "$1" = "--version" ]; then |
64 |
< |
cat <<EOF |
65 |
< |
tzselect $PKGVERSION$TZVERSION |
66 |
< |
EOF |
67 |
< |
exit |
60 |
> |
Options: |
61 |
> |
|
62 |
> |
-c COORD |
63 |
> |
Instead of asking for continent and then country and then city, |
64 |
> |
ask for selection from time zones whose largest cities |
65 |
> |
are closest to the location with geographical coordinates COORD. |
66 |
> |
COORD should use ISO 6709 notation, for example, '-c +4852+00220' |
67 |
> |
for Paris (in degrees and minutes, North and East), or |
68 |
> |
'-c -35-058' for Buenos Aires (in degrees, South and West). |
69 |
> |
|
70 |
> |
-n LIMIT |
71 |
> |
Display at most LIMIT locations when -c is used (default $location_limit). |
72 |
> |
|
73 |
> |
--version |
74 |
> |
Output version information. |
75 |
> |
|
76 |
> |
--help |
77 |
> |
Output this help. |
78 |
> |
|
79 |
> |
Report bugs to $REPORT_BUGS_TO." |
80 |
> |
|
81 |
> |
# Ask the user to select from the function's arguments, |
82 |
> |
# and assign the selected argument to the variable 'select_result'. |
83 |
> |
# Exit on EOF or I/O error. Use the shell's 'select' builtin if available, |
84 |
> |
# falling back on a less-nice but portable substitute otherwise. |
85 |
> |
if |
86 |
> |
case $BASH_VERSION in |
87 |
> |
?*) : ;; |
88 |
> |
'') |
89 |
> |
# '; exit' should be redundant, but Dash doesn't properly fail without it. |
90 |
> |
(eval 'set --; select x; do break; done; exit') </dev/null 2>/dev/null |
91 |
> |
esac |
92 |
> |
then |
93 |
> |
# Do this inside 'eval', as otherwise the shell might exit when parsing it |
94 |
> |
# even though it is never executed. |
95 |
> |
eval ' |
96 |
> |
doselect() { |
97 |
> |
select select_result |
98 |
> |
do |
99 |
> |
case $select_result in |
100 |
> |
"") echo >&2 "Please enter a number in range." ;; |
101 |
> |
?*) break |
102 |
> |
esac |
103 |
> |
done || exit |
104 |
> |
} |
105 |
> |
|
106 |
> |
# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout. |
107 |
> |
case $BASH_VERSION in |
108 |
> |
[01].*) |
109 |
> |
case `echo 1 | (select x in x; do break; done) 2>/dev/null` in |
110 |
> |
?*) PS3= |
111 |
> |
esac |
112 |
> |
esac |
113 |
> |
' |
114 |
> |
else |
115 |
> |
doselect() { |
116 |
> |
# Field width of the prompt numbers. |
117 |
> |
select_width=`expr $# : '.*'` |
118 |
> |
|
119 |
> |
select_i= |
120 |
> |
|
121 |
> |
while : |
122 |
> |
do |
123 |
> |
case $select_i in |
124 |
> |
'') |
125 |
> |
select_i=0 |
126 |
> |
for select_word |
127 |
> |
do |
128 |
> |
select_i=`expr $select_i + 1` |
129 |
> |
printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word" |
130 |
> |
done ;; |
131 |
> |
*[!0-9]*) |
132 |
> |
echo >&2 'Please enter a number in range.' ;; |
133 |
> |
*) |
134 |
> |
if test 1 -le $select_i && test $select_i -le $#; then |
135 |
> |
shift `expr $select_i - 1` |
136 |
> |
select_result=$1 |
137 |
> |
break |
138 |
> |
fi |
139 |
> |
echo >&2 'Please enter a number in range.' |
140 |
> |
esac |
141 |
> |
|
142 |
> |
# Prompt and read input. |
143 |
> |
printf >&2 %s "${PS3-#? }" |
144 |
> |
read select_i || exit |
145 |
> |
done |
146 |
> |
} |
147 |
|
fi |
148 |
|
|
149 |
+ |
while getopts c:n:t:-: opt |
150 |
+ |
do |
151 |
+ |
case $opt$OPTARG in |
152 |
+ |
c*) |
153 |
+ |
coord=$OPTARG ;; |
154 |
+ |
n*) |
155 |
+ |
location_limit=$OPTARG ;; |
156 |
+ |
t*) # Undocumented option, used for developer testing. |
157 |
+ |
zonetabtype=$OPTARG ;; |
158 |
+ |
-help) |
159 |
+ |
exec echo "$usage" ;; |
160 |
+ |
-version) |
161 |
+ |
exec echo "tzselect $PKGVERSION$TZVERSION" ;; |
162 |
+ |
-*) |
163 |
+ |
say >&2 "$0: -$opt$OPTARG: unknown option; try '$0 --help'"; exit 1 ;; |
164 |
+ |
*) |
165 |
+ |
say >&2 "$0: try '$0 --help'"; exit 1 ;; |
166 |
+ |
esac |
167 |
+ |
done |
168 |
+ |
|
169 |
+ |
shift `expr $OPTIND - 1` |
170 |
+ |
case $# in |
171 |
+ |
0) ;; |
172 |
+ |
*) say >&2 "$0: $1: unknown argument"; exit 1 ;; |
173 |
+ |
esac |
174 |
+ |
|
175 |
|
# Make sure the tables are readable. |
176 |
|
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab |
177 |
< |
TZ_ZONE_TABLE=$TZDIR/zone.tab |
177 |
> |
TZ_ZONE_TABLE=$TZDIR/$zonetabtype.tab |
178 |
|
for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE |
179 |
|
do |
180 |
< |
<$f || { |
181 |
< |
echo >&2 "$0: time zone files are not set up correctly" |
180 |
> |
<"$f" || { |
181 |
> |
say >&2 "$0: time zone files are not set up correctly" |
182 |
|
exit 1 |
183 |
|
} |
184 |
|
done |
185 |
|
|
186 |
+ |
# If the current locale does not support UTF-8, convert data to current |
187 |
+ |
# locale's format if possible, as the shell aligns columns better that way. |
188 |
+ |
# Check the UTF-8 of U+12345 CUNEIFORM SIGN URU TIMES KI. |
189 |
+ |
! $AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) != 1 }' && |
190 |
+ |
{ tmp=`(mktemp -d) 2>/dev/null` || { |
191 |
+ |
tmp=${TMPDIR-/tmp}/tzselect.$$ && |
192 |
+ |
(umask 77 && mkdir -- "$tmp") |
193 |
+ |
};} && |
194 |
+ |
trap 'status=$?; rm -fr -- "$tmp"; exit $status' 0 HUP INT PIPE TERM && |
195 |
+ |
(iconv -f UTF-8 -t //TRANSLIT <"$TZ_COUNTRY_TABLE" >$tmp/iso3166.tab) \ |
196 |
+ |
2>/dev/null && |
197 |
+ |
TZ_COUNTRY_TABLE=$tmp/iso3166.tab && |
198 |
+ |
iconv -f UTF-8 -t //TRANSLIT <"$TZ_ZONE_TABLE" >$tmp/$zonetabtype.tab && |
199 |
+ |
TZ_ZONE_TABLE=$tmp/$zonetabtype.tab |
200 |
+ |
|
201 |
|
newline=' |
202 |
|
' |
203 |
|
IFS=$newline |
204 |
|
|
205 |
|
|
206 |
< |
# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout. |
207 |
< |
case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in |
208 |
< |
?*) PS3= |
209 |
< |
esac |
206 |
> |
# Awk script to read a time zone table and output the same table, |
207 |
> |
# with each column preceded by its distance from 'here'. |
208 |
> |
output_distances=' |
209 |
> |
BEGIN { |
210 |
> |
FS = "\t" |
211 |
> |
while (getline <TZ_COUNTRY_TABLE) |
212 |
> |
if ($0 ~ /^[^#]/) |
213 |
> |
country[$1] = $2 |
214 |
> |
country["US"] = "US" # Otherwise the strings get too long. |
215 |
> |
} |
216 |
> |
function abs(x) { |
217 |
> |
return x < 0 ? -x : x; |
218 |
> |
} |
219 |
> |
function min(x, y) { |
220 |
> |
return x < y ? x : y; |
221 |
> |
} |
222 |
> |
function convert_coord(coord, deg, minute, ilen, sign, sec) { |
223 |
> |
if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) { |
224 |
> |
degminsec = coord |
225 |
> |
intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000) |
226 |
> |
minsec = degminsec - intdeg * 10000 |
227 |
> |
intmin = minsec < 0 ? -int(-minsec / 100) : int(minsec / 100) |
228 |
> |
sec = minsec - intmin * 100 |
229 |
> |
deg = (intdeg * 3600 + intmin * 60 + sec) / 3600 |
230 |
> |
} else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) { |
231 |
> |
degmin = coord |
232 |
> |
intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100) |
233 |
> |
minute = degmin - intdeg * 100 |
234 |
> |
deg = (intdeg * 60 + minute) / 60 |
235 |
> |
} else |
236 |
> |
deg = coord |
237 |
> |
return deg * 0.017453292519943296 |
238 |
> |
} |
239 |
> |
function convert_latitude(coord) { |
240 |
> |
match(coord, /..*[-+]/) |
241 |
> |
return convert_coord(substr(coord, 1, RLENGTH - 1)) |
242 |
> |
} |
243 |
> |
function convert_longitude(coord) { |
244 |
> |
match(coord, /..*[-+]/) |
245 |
> |
return convert_coord(substr(coord, RLENGTH)) |
246 |
> |
} |
247 |
> |
# Great-circle distance between points with given latitude and longitude. |
248 |
> |
# Inputs and output are in radians. This uses the great-circle special |
249 |
> |
# case of the Vicenty formula for distances on ellipsoids. |
250 |
> |
function gcdist(lat1, long1, lat2, long2, dlong, x, y, num, denom) { |
251 |
> |
dlong = long2 - long1 |
252 |
> |
x = cos(lat2) * sin(dlong) |
253 |
> |
y = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlong) |
254 |
> |
num = sqrt(x * x + y * y) |
255 |
> |
denom = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlong) |
256 |
> |
return atan2(num, denom) |
257 |
> |
} |
258 |
> |
# Parallel distance between points with given latitude and longitude. |
259 |
> |
# This is the product of the longitude difference and the cosine |
260 |
> |
# of the latitude of the point that is further from the equator. |
261 |
> |
# I.e., it considers longitudes to be further apart if they are |
262 |
> |
# nearer the equator. |
263 |
> |
function pardist(lat1, long1, lat2, long2) { |
264 |
> |
return abs(long1 - long2) * min(cos(lat1), cos(lat2)) |
265 |
> |
} |
266 |
> |
# The distance function is the sum of the great-circle distance and |
267 |
> |
# the parallel distance. It could be weighted. |
268 |
> |
function dist(lat1, long1, lat2, long2) { |
269 |
> |
return gcdist(lat1, long1, lat2, long2) + pardist(lat1, long1, lat2, long2) |
270 |
> |
} |
271 |
> |
BEGIN { |
272 |
> |
coord_lat = convert_latitude(coord) |
273 |
> |
coord_long = convert_longitude(coord) |
274 |
> |
} |
275 |
> |
/^[^#]/ { |
276 |
> |
here_lat = convert_latitude($2) |
277 |
> |
here_long = convert_longitude($2) |
278 |
> |
line = $1 "\t" $2 "\t" $3 |
279 |
> |
sep = "\t" |
280 |
> |
ncc = split($1, cc, /,/) |
281 |
> |
for (i = 1; i <= ncc; i++) { |
282 |
> |
line = line sep country[cc[i]] |
283 |
> |
sep = ", " |
284 |
> |
} |
285 |
> |
if (NF == 4) |
286 |
> |
line = line " - " $4 |
287 |
> |
printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line |
288 |
> |
} |
289 |
> |
' |
290 |
|
|
78 |
– |
|
291 |
|
# Begin the main loop. We come back here if the user wants to retry. |
292 |
|
while |
293 |
|
|
298 |
|
country= |
299 |
|
region= |
300 |
|
|
301 |
+ |
case $coord in |
302 |
+ |
?*) |
303 |
+ |
continent=coord;; |
304 |
+ |
'') |
305 |
|
|
306 |
|
# Ask the user for continent or ocean. |
307 |
|
|
308 |
< |
echo >&2 'Please select a continent or ocean.' |
308 |
> |
echo >&2 'Please select a continent, ocean, "coord", or "TZ".' |
309 |
|
|
310 |
< |
select continent in \ |
311 |
< |
Africa \ |
312 |
< |
Americas \ |
313 |
< |
Antarctica \ |
314 |
< |
'Arctic Ocean' \ |
315 |
< |
Asia \ |
316 |
< |
'Atlantic Ocean' \ |
317 |
< |
Australia \ |
318 |
< |
Europe \ |
319 |
< |
'Indian Ocean' \ |
320 |
< |
'Pacific Ocean' \ |
321 |
< |
'none - I want to specify the time zone using the Posix TZ format.' |
322 |
< |
do |
310 |
> |
quoted_continents=` |
311 |
> |
$AWK ' |
312 |
> |
BEGIN { FS = "\t" } |
313 |
> |
/^[^#]/ { |
314 |
> |
entry = substr($3, 1, index($3, "/") - 1) |
315 |
> |
if (entry == "America") |
316 |
> |
entry = entry "s" |
317 |
> |
if (entry ~ /^(Arctic|Atlantic|Indian|Pacific)$/) |
318 |
> |
entry = entry " Ocean" |
319 |
> |
printf "'\''%s'\''\n", entry |
320 |
> |
} |
321 |
> |
' <"$TZ_ZONE_TABLE" | |
322 |
> |
sort -u | |
323 |
> |
tr '\n' ' ' |
324 |
> |
echo '' |
325 |
> |
` |
326 |
> |
|
327 |
> |
eval ' |
328 |
> |
doselect '"$quoted_continents"' \ |
329 |
> |
"coord - I want to use geographical coordinates." \ |
330 |
> |
"TZ - I want to specify the time zone using the Posix TZ format." |
331 |
> |
continent=$select_result |
332 |
|
case $continent in |
333 |
< |
'') |
334 |
< |
echo >&2 'Please enter a number in range.';; |
110 |
< |
?*) |
111 |
< |
case $continent in |
112 |
< |
Americas) continent=America;; |
113 |
< |
*' '*) continent=$(expr "$continent" : '\([^ ]*\)') |
114 |
< |
esac |
115 |
< |
break |
333 |
> |
Americas) continent=America;; |
334 |
> |
*" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''` |
335 |
|
esac |
336 |
< |
done |
336 |
> |
' |
337 |
> |
esac |
338 |
> |
|
339 |
|
case $continent in |
340 |
< |
'') |
120 |
< |
exit 1;; |
121 |
< |
none) |
340 |
> |
TZ) |
341 |
|
# Ask the user for a Posix TZ string. Check that it conforms. |
342 |
|
while |
343 |
|
echo >&2 'Please enter the desired value' \ |
346 |
|
'that is 10 hours ahead (east) of UTC.' |
347 |
|
read TZ |
348 |
|
$AWK -v TZ="$TZ" 'BEGIN { |
349 |
< |
tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+" |
350 |
< |
time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?" |
349 |
> |
tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})" |
350 |
> |
time = "(2[0-4]|[0-1]?[0-9])" \ |
351 |
> |
"(:[0-5][0-9](:[0-5][0-9])?)?" |
352 |
|
offset = "[-+]?" time |
353 |
< |
date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)" |
354 |
< |
datetime = "," date "(/" time ")?" |
353 |
> |
mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]" |
354 |
> |
jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \ |
355 |
> |
"|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])" |
356 |
> |
datetime = ",(" mdate "|" jdate ")(/" time ")?" |
357 |
|
tzpattern = "^(:.*|" tzname offset "(" tzname \ |
358 |
|
"(" offset ")?(" datetime datetime ")?)?)$" |
359 |
|
if (TZ ~ tzpattern) exit 1 |
360 |
|
exit 0 |
361 |
|
}' |
362 |
|
do |
363 |
< |
echo >&2 "\`$TZ' is not a conforming" \ |
142 |
< |
'Posix time zone string.' |
363 |
> |
say >&2 "'$TZ' is not a conforming Posix time zone string." |
364 |
|
done |
365 |
|
TZ_for_date=$TZ;; |
366 |
|
*) |
367 |
+ |
case $continent in |
368 |
+ |
coord) |
369 |
+ |
case $coord in |
370 |
+ |
'') |
371 |
+ |
echo >&2 'Please enter coordinates' \ |
372 |
+ |
'in ISO 6709 notation.' |
373 |
+ |
echo >&2 'For example, +4042-07403 stands for' |
374 |
+ |
echo >&2 '40 degrees 42 minutes north,' \ |
375 |
+ |
'74 degrees 3 minutes west.' |
376 |
+ |
read coord;; |
377 |
+ |
esac |
378 |
+ |
distance_table=`$AWK \ |
379 |
+ |
-v coord="$coord" \ |
380 |
+ |
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ |
381 |
+ |
"$output_distances" <"$TZ_ZONE_TABLE" | |
382 |
+ |
sort -n | |
383 |
+ |
sed "${location_limit}q" |
384 |
+ |
` |
385 |
+ |
regions=`say "$distance_table" | $AWK ' |
386 |
+ |
BEGIN { FS = "\t" } |
387 |
+ |
{ print $NF } |
388 |
+ |
'` |
389 |
+ |
echo >&2 'Please select one of the following' \ |
390 |
+ |
'time zone regions,' |
391 |
+ |
echo >&2 'listed roughly in increasing order' \ |
392 |
+ |
"of distance from $coord". |
393 |
+ |
doselect $regions |
394 |
+ |
region=$select_result |
395 |
+ |
TZ=`say "$distance_table" | $AWK -v region="$region" ' |
396 |
+ |
BEGIN { FS="\t" } |
397 |
+ |
$NF == region { print $4 } |
398 |
+ |
'` |
399 |
+ |
;; |
400 |
+ |
*) |
401 |
|
# Get list of names of countries in the continent or ocean. |
402 |
< |
countries=$($AWK -F'\t' \ |
402 |
> |
countries=`$AWK \ |
403 |
|
-v continent="$continent" \ |
404 |
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ |
405 |
|
' |
406 |
+ |
BEGIN { FS = "\t" } |
407 |
|
/^#/ { next } |
408 |
|
$3 ~ ("^" continent "/") { |
409 |
< |
if (!cc_seen[$1]++) cc_list[++ccs] = $1 |
409 |
> |
ncc = split($1, cc, /,/) |
410 |
> |
for (i = 1; i <= ncc; i++) |
411 |
> |
if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i] |
412 |
|
} |
413 |
|
END { |
414 |
|
while (getline <TZ_COUNTRY_TABLE) { |
422 |
|
print country |
423 |
|
} |
424 |
|
} |
425 |
< |
' <$TZ_ZONE_TABLE | sort -f) |
425 |
> |
' <"$TZ_ZONE_TABLE" | sort -f` |
426 |
|
|
427 |
|
|
428 |
|
# If there's more than one country, ask the user which one. |
429 |
|
case $countries in |
430 |
|
*"$newline"*) |
431 |
< |
echo >&2 'Please select a country.' |
432 |
< |
select country in $countries |
433 |
< |
do |
434 |
< |
case $country in |
177 |
< |
'') echo >&2 'Please enter a number in range.';; |
178 |
< |
?*) break |
179 |
< |
esac |
180 |
< |
done |
181 |
< |
|
182 |
< |
case $country in |
183 |
< |
'') exit 1 |
184 |
< |
esac;; |
431 |
> |
echo >&2 'Please select a country' \ |
432 |
> |
'whose clocks agree with yours.' |
433 |
> |
doselect $countries |
434 |
> |
country=$select_result;; |
435 |
|
*) |
436 |
|
country=$countries |
437 |
|
esac |
438 |
|
|
439 |
|
|
440 |
|
# Get list of names of time zone rule regions in the country. |
441 |
< |
regions=$($AWK -F'\t' \ |
441 |
> |
regions=`$AWK \ |
442 |
|
-v country="$country" \ |
443 |
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ |
444 |
|
' |
445 |
|
BEGIN { |
446 |
+ |
FS = "\t" |
447 |
|
cc = country |
448 |
|
while (getline <TZ_COUNTRY_TABLE) { |
449 |
|
if ($0 !~ /^#/ && country == $2) { |
452 |
|
} |
453 |
|
} |
454 |
|
} |
455 |
< |
$1 == cc { print $4 } |
456 |
< |
' <$TZ_ZONE_TABLE) |
455 |
> |
/^#/ { next } |
456 |
> |
$1 ~ cc { print $4 } |
457 |
> |
' <"$TZ_ZONE_TABLE"` |
458 |
|
|
459 |
|
|
460 |
|
# If there's more than one region, ask the user which one. |
462 |
|
*"$newline"*) |
463 |
|
echo >&2 'Please select one of the following' \ |
464 |
|
'time zone regions.' |
465 |
< |
select region in $regions |
466 |
< |
do |
215 |
< |
case $region in |
216 |
< |
'') echo >&2 'Please enter a number in range.';; |
217 |
< |
?*) break |
218 |
< |
esac |
219 |
< |
done |
220 |
< |
case $region in |
221 |
< |
'') exit 1 |
222 |
< |
esac;; |
465 |
> |
doselect $regions |
466 |
> |
region=$select_result;; |
467 |
|
*) |
468 |
|
region=$regions |
469 |
|
esac |
470 |
|
|
471 |
|
# Determine TZ from country and region. |
472 |
< |
TZ=$($AWK -F'\t' \ |
472 |
> |
TZ=`$AWK \ |
473 |
|
-v country="$country" \ |
474 |
|
-v region="$region" \ |
475 |
|
-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ |
476 |
|
' |
477 |
|
BEGIN { |
478 |
+ |
FS = "\t" |
479 |
|
cc = country |
480 |
|
while (getline <TZ_COUNTRY_TABLE) { |
481 |
|
if ($0 !~ /^#/ && country == $2) { |
484 |
|
} |
485 |
|
} |
486 |
|
} |
487 |
< |
$1 == cc && $4 == region { print $3 } |
488 |
< |
' <$TZ_ZONE_TABLE) |
487 |
> |
/^#/ { next } |
488 |
> |
$1 ~ cc && $4 == region { print $3 } |
489 |
> |
' <"$TZ_ZONE_TABLE"` |
490 |
> |
esac |
491 |
|
|
492 |
|
# Make sure the corresponding zoneinfo file exists. |
493 |
|
TZ_for_date=$TZDIR/$TZ |
494 |
< |
<$TZ_for_date || { |
495 |
< |
echo >&2 "$0: time zone files are not set up correctly" |
494 |
> |
<"$TZ_for_date" || { |
495 |
> |
say >&2 "$0: time zone files are not set up correctly" |
496 |
|
exit 1 |
497 |
|
} |
498 |
|
esac |
505 |
|
extra_info= |
506 |
|
for i in 1 2 3 4 5 6 7 8 |
507 |
|
do |
508 |
< |
TZdate=$(LANG=C TZ="$TZ_for_date" date) |
509 |
< |
UTdate=$(LANG=C TZ=UTC0 date) |
510 |
< |
TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)') |
511 |
< |
UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)') |
508 |
> |
TZdate=`LANG=C TZ="$TZ_for_date" date` |
509 |
> |
UTdate=`LANG=C TZ=UTC0 date` |
510 |
> |
TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'` |
511 |
> |
UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'` |
512 |
|
case $TZsec in |
513 |
|
$UTsec) |
514 |
|
extra_info=" |
515 |
< |
Local time is now: $TZdate. |
515 |
> |
Selected time is now: $TZdate. |
516 |
|
Universal Time is now: $UTdate." |
517 |
|
break |
518 |
|
esac |
524 |
|
echo >&2 "" |
525 |
|
echo >&2 "The following information has been given:" |
526 |
|
echo >&2 "" |
527 |
< |
case $country+$region in |
528 |
< |
?*+?*) echo >&2 " $country$newline $region";; |
529 |
< |
?*+) echo >&2 " $country";; |
530 |
< |
+) echo >&2 " TZ='$TZ'" |
527 |
> |
case $country%$region%$coord in |
528 |
> |
?*%?*%) say >&2 " $country$newline $region";; |
529 |
> |
?*%%) say >&2 " $country";; |
530 |
> |
%?*%?*) say >&2 " coord $coord$newline $region";; |
531 |
> |
%%?*) say >&2 " coord $coord";; |
532 |
> |
*) say >&2 " TZ='$TZ'" |
533 |
|
esac |
534 |
< |
echo >&2 "" |
535 |
< |
echo >&2 "Therefore TZ='$TZ' will be used.$extra_info" |
536 |
< |
echo >&2 "Is the above information OK?" |
534 |
> |
say >&2 "" |
535 |
> |
say >&2 "Therefore TZ='$TZ' will be used.$extra_info" |
536 |
> |
say >&2 "Is the above information OK?" |
537 |
|
|
538 |
< |
ok= |
539 |
< |
select ok in Yes No |
291 |
< |
do |
292 |
< |
case $ok in |
293 |
< |
'') echo >&2 'Please enter 1 for Yes, or 2 for No.';; |
294 |
< |
?*) break |
295 |
< |
esac |
296 |
< |
done |
538 |
> |
doselect Yes No |
539 |
> |
ok=$select_result |
540 |
|
case $ok in |
298 |
– |
'') exit 1;; |
541 |
|
Yes) break |
542 |
|
esac |
543 |
< |
do : |
543 |
> |
do coord= |
544 |
|
done |
545 |
|
|
546 |
|
case $SHELL in |
548 |
|
*) file=.profile line="TZ='$TZ'; export TZ" |
549 |
|
esac |
550 |
|
|
551 |
< |
echo >&2 " |
551 |
> |
test -t 1 && say >&2 " |
552 |
|
You can make this change permanent for yourself by appending the line |
553 |
|
$line |
554 |
|
to the file '$file' in your home directory; then log out and log in again. |
556 |
|
Here is that TZ value again, this time on standard output so that you |
557 |
|
can use the $0 command in shell scripts:" |
558 |
|
|
559 |
< |
echo "$TZ" |
559 |
> |
say "$TZ" |