Skip to content

Instantly share code, notes, and snippets.

@livibetter
Forked from Goles/cliclock.sh
Created June 15, 2012 00:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save livibetter/2933746 to your computer and use it in GitHub Desktop.
Save livibetter/2933746 to your computer and use it in GitHub Desktop.
Command-line script for displaying world clocks, allows zonefiles or zone names inputs.

cliclock.sh

Command-line script for displaying world clocks, allows zonefiles or zone names inputs.

Forked from Gist, which was from an Stackoverflow answer.

Heavily modified by Yu-Jie Lin.

#!/bin/sh
# Command-line world clock
# Taken from http://stackoverflow.com/questions/370075/command-line-world-clock
# Modified by Yu-Jie Lin
# usage:
# cliclock.sh [[zonefile|zonename] ...]
#
# zonename can be full or partial, e.g. America/New_York or 'new york'
#
# default ~/.worldclock.zones and zonefile looks like:
# US/Pacific
# Europe/Berlin
# Chile/Continental
# new york
# Los Angeles
: ${WORLDCLOCK_FORMAT:='%Y-%m-%d %H:%M:%S %Z'}
if (( $# == 0 )); then
: ${WORLDCLOCK_ZONES:=$HOME/.worldclock.zones}
if [[ ! -f $WORLDCLOCK_ZONES ]]; then
echo 'no zones to display' >&2
exit 1
fi
OLDIFS="$IFS"
IFS=$'\n'
WORLDCLOCK_ZONES=($(cat "$WORLDCLOCK_ZONES"))
IFS="$OLDIFS"
else
while (( $# > 0)); do
if [[ -f "$1" ]]; then
OLDIFS="$IFS"
IFS=$'\n'
WORLDCLOCK_ZONES=("${WORLDCLOCK_ZONES[@]}" $(cat "$1"))
IFS="$OLDIFS"
else
WORLDCLOCK_ZONES=("${WORLDCLOCK_ZONES[@]}" "$1")
fi
shift
done
fi
ZONEINFO='/usr/share/zoneinfo/'
VALID_ZONES=($(find "$ZONEINFO" -path '*/right' -prune -o -type f | sed "s|^$ZONEINFO||"))
shopt -s nocasematch
# Checking zones and set the max length
check_zone() {
local zone z
ret=
z="*${1// /?}*"
for zone in "${VALID_ZONES[@]}"; do
if [[ $zone == $z ]]; then
ret="$zone"
return
fi
# match first zone with $zone as substring
if [[ ! -z $ret ]] && [[ $zone == $z ]]; then
ret="$zone"
fi
done
}
zones=()
MAX_ZONE_LEN=0
for zone in "${WORLDCLOCK_ZONES[@]}"; do
check_zone "$zone"
if [[ -z $ret ]]; then
echo invalid zone $zone >&2
continue
fi
zone="$ret"
zones=("${zones[@]}" "$zone")
(( ${#zone} > MAX_ZONE_LEN )) && MAX_ZONE_LEN=${#zone}
done
unset VALID_ZONES
if (( ${#zones[@]} == 0 )); then
echo 'no zones to display' >&2
exit 1
fi
# Some zones are invalid, keep error message for 3 seconds
(( ${#zones[@]} != ${#WORLDCLOCK_ZONES[@]} )) && sleep 3
unset WORLDCLOCK_ZONES
while :; do
clear
printf -v now '%(%s)T' -1
for zone in "${zones[@]}"; do
TZ=$zone printf "%-${MAX_ZONE_LEN}s %($WORLDCLOCK_FORMAT)T\n" "$zone" "$now"
done
# Allow to elegantly quit this script
if read -n 1 -t 1 -s; then
case "$REPLY" in
q|Q)
break
;;
esac
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment