tz (2754B)
1 #!/bin/sh 2 # Convert between time zones. 3 # Depends on GNU date because of the `-d` switch, and fzf for choosing. 4 die() { printf '%s\n' "$1" >&2 && exit 1; } 5 6 command -v fzf >/dev/null 2>&1 || die 'fzf required for timezone selection.' 7 8 # Check for GNU date 9 if command -v gdate >/dev/null 2>&1; then 10 datecmd='gdate' 11 elif command -v date --version >/dev/null 2>&1; then 12 datecmd='date' 13 else 14 die 'GNU `date` required but not detected.' 15 fi 16 17 # Get path to timezones 18 zonedir="$(realpath /usr/share/zoneinfo)" 19 20 PARAMS="" 21 22 while [ $(($#)) -ne 0 ]; do 23 case "$1" in 24 -tc|--target-current) 25 tzhere="$(realpath /etc/localtime | sed "s!$zonedir/!!")" 26 target="$tzhere" 27 shift 28 ;; 29 -sc|--source-current) 30 tzhere="$(realpath /etc/localtime | sed "s!$zonedir/!!")" 31 src="$tzhere" 32 shift 33 ;; 34 -s|--source) 35 src="$2" 36 stat "$zonedir"/"$src" >/dev/null 2>&1 || die "Source time zone $src invalid." 37 shift 2 38 ;; 39 -t|--target) 40 target="$2" 41 stat "$zonedir"/"$target" >/dev/null 2>&1 || die "Source time zone $target invalid." 42 shift 2 43 ;; 44 -h|--help) 45 printf 'USAGE\n' 46 printf 'Switches:\n' 47 printf '%s\t%s\n' '-tc|--target-current' 'use current time zone as target' 48 printf '%s\t%s\n' '-sc|--source-current' 'use current time zone as source' 49 printf '%s\t%s\n' '-s|--source TZ' 'use TZ as source' 50 printf '%s\t%s\n' '-t|--target TZ' 'use TZ as target' 51 printf '\nExamples:\n' 52 printf '%s\n' '- What time is it right now in some time zone? Run: `tz -sc`, choose target time zone interactively.' 53 printf '%s\n' '- What is 3 PM Eastern Standard Time in Amsterdam? Run: `tz -s "EST" -t "Europe/Amsterdam" "3pm"`' 54 printf '%s\n' '- What is 11 AM in one time zone when converted to another time zone? Run: `tz "11am"`, choose source and target time zone interactively.' 55 exit 0 56 ;; 57 --) # end arg parsing 58 shift 59 break 60 ;; 61 -*) # unsupported flags 62 echo "Unsupported flag $1" >&2 63 exit 1 64 ;; 65 *) # preserve positional arguments 66 # if params is set, add space. 67 PARAMS="$PARAMS${PARAMS:+ }$1" 68 shift 69 ;; 70 esac 71 done 72 set -- "$PARAMS" 73 74 if [ -z "$src" ]; then # we have to interactively prompt for source 75 src="$(find "$zonedir" -type f | sed "s!$zonedir/!!" | fzf --prompt='Source > ' --layout=reverse)" 76 [ -z "$src" ] && exit 0 77 fi 78 if [ -z "$target" ]; then # we have to interactively prompt for target 79 target="$(find "$zonedir" -type f | sed "s!$zonedir/!!" | fzf --prompt='Target > ' --layout=reverse)" 80 [ -z "$target" ] && exit 0 81 fi 82 83 84 time="${1:-now}" 85 TZ="$target" "$datecmd" -d "TZ=\"$src\" $time" 86 printf 'From: %s (%s)\nTo: %s' "$time" "$src" "$target"