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