intl/icu/source/tools/tzcode/tzselect.ksh

changeset 0
6474c204b198
     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"

mercurial