Skip to content

Instantly share code, notes, and snippets.

@schauveau
Last active June 8, 2021 13:32
Show Gist options
  • Save schauveau/c45b396f22101622aee35a9854050f5e to your computer and use it in GitHub Desktop.
Save schauveau/c45b396f22101622aee35a9854050f5e to your computer and use it in GitHub Desktop.
Bash function to display a given time in multiple timezones
#!/bin/bash
# tz <TIME SPECIFICATION>
#
# Display the specified time in multiple timezones.
#
# If no time is specified then "now" is used.
#
# You may want to customize the ZONES array below with your
# favorite timezone names (see also tzselect)
#
# Timezones are automatically sorted by their UTC offsets.
#
# Timezones with the same UTC offset than the local timezone
# are marked with '*'
#
# However, they are marked with '?' instead if the UTC offset
# for the current time and for the specified time are not equal.
# That typically indicates a summer/winter time change between
# the two dates.
#
# See 'info date' for a full description of the supported time
# and date formats.
#
# Examples:
#
# tz : for the current time (or "now")
# tz 14:00 : for 14:00 today in the current timezone
# tz 14:00+4 : for 14:00 today in UTC+4
# tz tomorrow 2pm PST : for 14:00 tomorrow in Pacific Standard Time
# tz 2pm July 3 CEST : for Friday July 3 14:00 2015 in Central European Summer Time
#
# Remark: Not all symbolic timezone names work as expected.
# First because some of them are only valid during parts of
# the year (e.g CET vs CEST in Central Europe) and also because
# some names are ambiguous (e.g. CST may refer to Central Standard
# Time in the USA or to the China Standard Time in China).
# Using UTC or GMT relative timezones is usually safer.
#
# http://www.timeanddate.com/time/map/
#
tz () {
local FMT A D T tz M UTC0 UTC1 UTC2 ZONES
D="$*"
# Output format (see man 1 date)
FMT="%H:%M %_4Z (UTC%:z) %a %b %d"
# FMT="%c %Z (UTC%:z)"
[ -n "$D" ] || D=now
T=$(date -d "$D" +%s) || return
# Add here your preferred locations (as given by tzselect)
ZONES=(
America/Los_Angeles # PST/PDT
# America/Denver # MST/MDT
America/Chicago # CST/CDT
America/New_York # EST/EDT
Europe/London # GMT/BST
Europe/Paris # CET/CEST
# Asia/Shanghai # CST (China Standard Time)
Asia/Tokyo # JST
# Australia/Melbourne # AEDT/AEST
# Australia/Adelaide # ACDT/ACST
)
# Get current timezone now (in $UTC0) and at requested time (in $UTC1)
# They may be different because of summer/winter time changes.
UTC0=$(LC_ALL=C date -d "now" +"%z")
UTC1=$(LC_ALL=C date -d "@$T" +"%z")
for tz in "${ZONES[@]}" ; do
# UTC2 is the UTC timezone of $tz at the given time
UTC2=$(LC_ALL=C TZ="$tz" date -d "@$T" +"%z")
XX=$?
if [[ "$UTC1" == "$UTC2" ]] ; then
if [[ "$UTC0" == "$UTC1" ]] ; then
M="*" # This is consistent with current timezone.
else
M="?" # Also but probably with a summer/winter time change.
fi
else
M=" "
fi
A=$(LC_ALL=C TZ="$tz" date -d "@$T" +"$FMT")
# Prefix each output line with its numeric timezone.
# That prefix will we removed after sorting.
printf "%s %c%-20s %s $XX\n" "$UTC2" "$M" "$tz" "$A"
done | sort -n | cut -c 7-
}
tz "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment