1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/tools/tzcode/tzselect.ksh Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 1.4 +#! /bin/ksh 1.5 + 1.6 +# '@(#)tzselect.ksh 8.1' 1.7 + 1.8 +# Ask the user about the time zone, and output the resulting TZ value to stdout. 1.9 +# Interact with the user via stderr and stdin. 1.10 + 1.11 +# Contributed by Paul Eggert. 1.12 + 1.13 +# Porting notes: 1.14 +# 1.15 +# This script requires several features of the Korn shell. 1.16 +# If your host lacks the Korn shell, 1.17 +# you can use either of the following free programs instead: 1.18 +# 1.19 +# <a href=ftp://ftp.gnu.org/pub/gnu/> 1.20 +# Bourne-Again shell (bash) 1.21 +# </a> 1.22 +# 1.23 +# <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz> 1.24 +# Public domain ksh 1.25 +# </a> 1.26 +# 1.27 +# This script also uses several features of modern awk programs. 1.28 +# If your host lacks awk, or has an old awk that does not conform to Posix.2, 1.29 +# you can use either of the following free programs instead: 1.30 +# 1.31 +# <a href=ftp://ftp.gnu.org/pub/gnu/> 1.32 +# GNU awk (gawk) 1.33 +# </a> 1.34 +# 1.35 +# <a href=ftp://ftp.whidbey.net/pub/brennan/> 1.36 +# mawk 1.37 +# </a> 1.38 + 1.39 + 1.40 +# Specify default values for environment variables if they are unset. 1.41 +: ${AWK=awk} 1.42 +: ${TZDIR=$(pwd)} 1.43 + 1.44 +# Check for awk Posix compliance. 1.45 +($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1 1.46 +[ $? = 123 ] || { 1.47 + echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible." 1.48 + exit 1 1.49 +} 1.50 + 1.51 +# Make sure the tables are readable. 1.52 +TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab 1.53 +TZ_ZONE_TABLE=$TZDIR/zone.tab 1.54 +for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE 1.55 +do 1.56 + <$f || { 1.57 + echo >&2 "$0: time zone files are not set up correctly" 1.58 + exit 1 1.59 + } 1.60 +done 1.61 + 1.62 +newline=' 1.63 +' 1.64 +IFS=$newline 1.65 + 1.66 + 1.67 +# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout. 1.68 +case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in 1.69 +?*) PS3= 1.70 +esac 1.71 + 1.72 + 1.73 +# Begin the main loop. We come back here if the user wants to retry. 1.74 +while 1.75 + 1.76 + echo >&2 'Please identify a location' \ 1.77 + 'so that time zone rules can be set correctly.' 1.78 + 1.79 + continent= 1.80 + country= 1.81 + region= 1.82 + 1.83 + 1.84 + # Ask the user for continent or ocean. 1.85 + 1.86 + echo >&2 'Please select a continent or ocean.' 1.87 + 1.88 + select continent in \ 1.89 + Africa \ 1.90 + Americas \ 1.91 + Antarctica \ 1.92 + 'Arctic Ocean' \ 1.93 + Asia \ 1.94 + 'Atlantic Ocean' \ 1.95 + Australia \ 1.96 + Europe \ 1.97 + 'Indian Ocean' \ 1.98 + 'Pacific Ocean' \ 1.99 + 'none - I want to specify the time zone using the Posix TZ format.' 1.100 + do 1.101 + case $continent in 1.102 + '') 1.103 + echo >&2 'Please enter a number in range.';; 1.104 + ?*) 1.105 + case $continent in 1.106 + Americas) continent=America;; 1.107 + *' '*) continent=$(expr "$continent" : '\([^ ]*\)') 1.108 + esac 1.109 + break 1.110 + esac 1.111 + done 1.112 + case $continent in 1.113 + '') 1.114 + exit 1;; 1.115 + none) 1.116 + # Ask the user for a Posix TZ string. Check that it conforms. 1.117 + while 1.118 + echo >&2 'Please enter the desired value' \ 1.119 + 'of the TZ environment variable.' 1.120 + echo >&2 'For example, GST-10 is a zone named GST' \ 1.121 + 'that is 10 hours ahead (east) of UTC.' 1.122 + read TZ 1.123 + $AWK -v TZ="$TZ" 'BEGIN { 1.124 + tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+" 1.125 + time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?" 1.126 + offset = "[-+]?" time 1.127 + date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)" 1.128 + datetime = "," date "(/" time ")?" 1.129 + tzpattern = "^(:.*|" tzname offset "(" tzname \ 1.130 + "(" offset ")?(" datetime datetime ")?)?)$" 1.131 + if (TZ ~ tzpattern) exit 1 1.132 + exit 0 1.133 + }' 1.134 + do 1.135 + echo >&2 "\`$TZ' is not a conforming" \ 1.136 + 'Posix time zone string.' 1.137 + done 1.138 + TZ_for_date=$TZ;; 1.139 + *) 1.140 + # Get list of names of countries in the continent or ocean. 1.141 + countries=$($AWK -F'\t' \ 1.142 + -v continent="$continent" \ 1.143 + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ 1.144 + ' 1.145 + /^#/ { next } 1.146 + $3 ~ ("^" continent "/") { 1.147 + if (!cc_seen[$1]++) cc_list[++ccs] = $1 1.148 + } 1.149 + END { 1.150 + while (getline <TZ_COUNTRY_TABLE) { 1.151 + if ($0 !~ /^#/) cc_name[$1] = $2 1.152 + } 1.153 + for (i = 1; i <= ccs; i++) { 1.154 + country = cc_list[i] 1.155 + if (cc_name[country]) { 1.156 + country = cc_name[country] 1.157 + } 1.158 + print country 1.159 + } 1.160 + } 1.161 + ' <$TZ_ZONE_TABLE | sort -f) 1.162 + 1.163 + 1.164 + # If there's more than one country, ask the user which one. 1.165 + case $countries in 1.166 + *"$newline"*) 1.167 + echo >&2 'Please select a country.' 1.168 + select country in $countries 1.169 + do 1.170 + case $country in 1.171 + '') echo >&2 'Please enter a number in range.';; 1.172 + ?*) break 1.173 + esac 1.174 + done 1.175 + 1.176 + case $country in 1.177 + '') exit 1 1.178 + esac;; 1.179 + *) 1.180 + country=$countries 1.181 + esac 1.182 + 1.183 + 1.184 + # Get list of names of time zone rule regions in the country. 1.185 + regions=$($AWK -F'\t' \ 1.186 + -v country="$country" \ 1.187 + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ 1.188 + ' 1.189 + BEGIN { 1.190 + cc = country 1.191 + while (getline <TZ_COUNTRY_TABLE) { 1.192 + if ($0 !~ /^#/ && country == $2) { 1.193 + cc = $1 1.194 + break 1.195 + } 1.196 + } 1.197 + } 1.198 + $1 == cc { print $4 } 1.199 + ' <$TZ_ZONE_TABLE) 1.200 + 1.201 + 1.202 + # If there's more than one region, ask the user which one. 1.203 + case $regions in 1.204 + *"$newline"*) 1.205 + echo >&2 'Please select one of the following' \ 1.206 + 'time zone regions.' 1.207 + select region in $regions 1.208 + do 1.209 + case $region in 1.210 + '') echo >&2 'Please enter a number in range.';; 1.211 + ?*) break 1.212 + esac 1.213 + done 1.214 + case $region in 1.215 + '') exit 1 1.216 + esac;; 1.217 + *) 1.218 + region=$regions 1.219 + esac 1.220 + 1.221 + # Determine TZ from country and region. 1.222 + TZ=$($AWK -F'\t' \ 1.223 + -v country="$country" \ 1.224 + -v region="$region" \ 1.225 + -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \ 1.226 + ' 1.227 + BEGIN { 1.228 + cc = country 1.229 + while (getline <TZ_COUNTRY_TABLE) { 1.230 + if ($0 !~ /^#/ && country == $2) { 1.231 + cc = $1 1.232 + break 1.233 + } 1.234 + } 1.235 + } 1.236 + $1 == cc && $4 == region { print $3 } 1.237 + ' <$TZ_ZONE_TABLE) 1.238 + 1.239 + # Make sure the corresponding zoneinfo file exists. 1.240 + TZ_for_date=$TZDIR/$TZ 1.241 + <$TZ_for_date || { 1.242 + echo >&2 "$0: time zone files are not set up correctly" 1.243 + exit 1 1.244 + } 1.245 + esac 1.246 + 1.247 + 1.248 + # Use the proposed TZ to output the current date relative to UTC. 1.249 + # Loop until they agree in seconds. 1.250 + # Give up after 8 unsuccessful tries. 1.251 + 1.252 + extra_info= 1.253 + for i in 1 2 3 4 5 6 7 8 1.254 + do 1.255 + TZdate=$(LANG=C TZ="$TZ_for_date" date) 1.256 + UTdate=$(LANG=C TZ=UTC0 date) 1.257 + TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)') 1.258 + UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)') 1.259 + case $TZsec in 1.260 + $UTsec) 1.261 + extra_info=" 1.262 +Local time is now: $TZdate. 1.263 +Universal Time is now: $UTdate." 1.264 + break 1.265 + esac 1.266 + done 1.267 + 1.268 + 1.269 + # Output TZ info and ask the user to confirm. 1.270 + 1.271 + echo >&2 "" 1.272 + echo >&2 "The following information has been given:" 1.273 + echo >&2 "" 1.274 + case $country+$region in 1.275 + ?*+?*) echo >&2 " $country$newline $region";; 1.276 + ?*+) echo >&2 " $country";; 1.277 + +) echo >&2 " TZ='$TZ'" 1.278 + esac 1.279 + echo >&2 "" 1.280 + echo >&2 "Therefore TZ='$TZ' will be used.$extra_info" 1.281 + echo >&2 "Is the above information OK?" 1.282 + 1.283 + ok= 1.284 + select ok in Yes No 1.285 + do 1.286 + case $ok in 1.287 + '') echo >&2 'Please enter 1 for Yes, or 2 for No.';; 1.288 + ?*) break 1.289 + esac 1.290 + done 1.291 + case $ok in 1.292 + '') exit 1;; 1.293 + Yes) break 1.294 + esac 1.295 +do : 1.296 +done 1.297 + 1.298 +case $SHELL in 1.299 +*csh) file=.login line="setenv TZ '$TZ'";; 1.300 +*) file=.profile line="TZ='$TZ'; export TZ" 1.301 +esac 1.302 + 1.303 +echo >&2 " 1.304 +You can make this change permanent for yourself by appending the line 1.305 + $line 1.306 +to the file '$file' in your home directory; then log out and log in again. 1.307 + 1.308 +Here is that TZ value again, this time on standard output so that you 1.309 +can use the $0 command in shell scripts:" 1.310 + 1.311 +echo "$TZ"