Is there a script to display a simple world clock (time in various places around the world) on a *nix terminal?
I was thinking of writing a quick Python script, but I have a feeling that's gonna be more work than I think (eg due to config and output format) - not to mention reinventing the wheel...
I have this bourne shell script:
#!/bin/sh
PT=`env TZ=US/Pacific date`
CT=`env TZ=US/Central date`
AT=`env TZ=Australia/Melbourne date`
echo "Santa Clara $PT"
echo "Central $CT"
echo "Melbourne $AT"
Never thought of it, but not dreadfully hard to do.
#!/bin/sh
# Command-line world clock
: ${WORLDCLOCK_ZONES:=$HOME/etc/worldclock.zones}
: ${WORLDCLOCK_FORMAT:='+%Y-%m-%d %H:%M:%S %Z'}
while read zone
do echo $zone '!' $(TZ=$zone date "$WORLDCLOCK_FORMAT")
done < $WORLDCLOCK_ZONES |
awk -F '!' '{ printf "%-20s %s\n", $1, $2;}'
Given the input file:
US/Pacific
Europe/London
Europe/Paris
Asia/Kolkatta
Africa/Johannesburg
Asia/Tokyo
Asia/Shanghai
I got the output:
US/Pacific 2008-12-15 15:58:57 PST
Europe/London 2008-12-15 23:58:57 GMT
Europe/Paris 2008-12-16 00:58:57 CET
Asia/Kolkatta 2008-12-15 23:58:57 GMT
Africa/Johannesburg 2008-12-16 01:58:57 SAST
Asia/Tokyo 2008-12-16 08:58:57 JST
Asia/Shanghai 2008-12-16 07:58:57 CST
I was fortunate that this took less than a second to run and didn't cross a 1-second boundary.
( I didn't notice that Kolkatta failed and defaulted to GMT. Maybe my system still has Asia/Calcutta as the entry for India. )
Eleven years later, I'm told that I misspelt Kolkata with two t's where there should only be one; thank you, @ jbg . I've also added two extra entries to the data file — America/St_Johns
(Newfoundland) and Asia/Katmandu
which have a half-hour and three-quarter hour offset from UTC respectively (Kolkata also has a half-hour offset). That produces, for example:
US/Pacific 2020-01-09 06:17:40 PST
Europe/London 2020-01-09 14:17:40 GMT
Europe/Paris 2020-01-09 15:17:40 CET
Asia/Kolkata 2020-01-09 19:47:40 IST
Africa/Johannesburg 2020-01-09 16:17:40 SAST
Asia/Tokyo 2020-01-09 23:17:40 JST
Asia/Shanghai 2020-01-09 22:17:40 CST
America/St_Johns 2020-01-09 10:47:40 NST
Asia/Katmandu 2020-01-09 20:02:40 +0545
Note that US/Pacific
is an ancient time zone name that is not preferred; it should be America/Los_Angeles
.
It might be sensible to sort the zones into order. Add sort -b -r -k2,2 -k3,3
to list the zones in the order with the time zones furthest ahead of UTC listed first and those farthest behind listed last. The -b
option (to ignore leading blanks on fields) is important. Adding three more zones ( Pacific/Honolulu
, Pacific/Kwajalein
, Pacific/Kiritimati
) and that gives:
Pacific/Kiritimati 2020-01-10 04:33:25 +14
Pacific/Kwajalein 2020-01-10 02:33:25 +12
Asia/Tokyo 2020-01-09 23:33:25 JST
Asia/Shanghai 2020-01-09 22:33:25 CST
Asia/Katmandu 2020-01-09 20:18:25 +0545
Asia/Kolkata 2020-01-09 20:03:25 IST
Africa/Johannesburg 2020-01-09 16:33:25 SAST
Europe/Paris 2020-01-09 15:33:25 CET
Europe/London 2020-01-09 14:33:25 GMT
America/St_Johns 2020-01-09 11:03:25 NST
US/Pacific 2020-01-09 06:33:25 PST
Pacific/Honolulu 2020-01-09 04:33:25 HST
Note that the time in Kiritimati and Honolulu is the same, but the date is one day apart. The sorting should be in the script, of course:
#!/bin/sh
# Command-line world clock
: ${WORLDCLOCK_ZONES:=$HOME/etc/worldclock.zones}
: ${WORLDCLOCK_FORMAT:='+%Y-%m-%d %H:%M:%S %Z'}
while read zone
do echo $zone '!' $(TZ=$zone date "$WORLDCLOCK_FORMAT")
done < $WORLDCLOCK_ZONES |
awk -F '!' '{ printf "%-20s %s\n", $1, $2;}' |
sort -b -r -k2,2 -k3,3
And the worldclock.zones
file contains:
US/Pacific
Europe/London
Europe/Paris
Asia/Kolkata
Africa/Johannesburg
Asia/Tokyo
Asia/Shanghai
America/St_Johns
Asia/Katmandu
Pacific/Honolulu
Pacific/Kwajalein
Pacific/Kiritimati
Pacific/Pago_Pago
UTC-12
Kiritimati has the most positive offset from UTC at UTC+14. Pacific/Pago_Pago
is one of the places with the most negative offset from UTC at UTC-11. If you go to World Time Zone , they list two uninhabited islands that would, if inhabited, probably be in UTC-12. However, the Olson database doesn't record time zone information for places uninhabited since its cutoff date of 1970-01-01, so they're not listed.
For entertainment (simple minds are easily side-tracked), here's a list of time zone names with one name from most of the time zone offsets around the world. If there are any other fractional-hour offsets in use (Australia?), please let me know. Beware of standard vs daylight saving time — some entries for the southern hemisphere may be in daylight saving time. In January 2020, the list generates all the integral-hour offsets, but it might not do so in June 2020.
The list includes two made up zone names: FarEast-12
and FarWest+12
, which are at UTC+12 and UTC-12 respectively. This conflict between positive and negative arises because there are conflicting standards. ISO 8601 specifies that places east of UTC (the Greenwich Meridian, more or less) use positive offsets from UTC, and those west of UTC use negative offsets. Meanwhile, POSIX (aka ISO 9045), specifies the opposite convention — places west of UTC use a positive offset and those east use a negative offset. Those two names are POSIX time zone names for use with the TZ environment variable and are specified with an offset and no daylight saving rule. They are subject to the POSIX offset rules. Why the discrepancy? Fundamentally, POSIX followed the conventions of Unix — it couldn't change them without breaking a lot of code. ISO 8601 was independent of POSIX and derived the rules from first principles and came up with a sensible system — but the converse of POSIX.
List of zone names:
US/Pacific
Europe/London
Europe/Paris
Asia/Kolkata
Africa/Johannesburg
Asia/Tokyo
Asia/Shanghai
America/St_Johns
Asia/Katmandu
Pacific/Honolulu
Pacific/Kwajalein
Pacific/Kiritimati
Pacific/Pago_Pago
FarEast-12
FarWest+12
US/Eastern
US/Central
US/Mountain
US/Alaska
Asia/Vladivostok
Pacific/Noumea
Pacific/Enderbury
Asia/Bangkok
Asia/Thimphu
Asia/Aqtau
Asia/Dubai
Africa/Addis_Ababa
Atlantic/Cape_Verde
Atlantic/South_Georgia
America/Santiago
America/Halifax
Sample output from modified script (with sort in place):
Pacific/Kiritimati 2020-01-10 05:24:10 +14
Pacific/Enderbury 2020-01-10 04:24:10 +13
Pacific/Kwajalein 2020-01-10 03:24:10 +12
FarEast-12 2020-01-10 03:24:10 FarEast
Pacific/Noumea 2020-01-10 02:24:10 +11
Asia/Vladivostok 2020-01-10 01:24:10 +10
Asia/Tokyo 2020-01-10 00:24:10 JST
Asia/Shanghai 2020-01-09 23:24:10 CST
Asia/Bangkok 2020-01-09 22:24:10 +07
Asia/Thimphu 2020-01-09 21:24:10 +06
Asia/Katmandu 2020-01-09 21:09:10 +0545
Asia/Kolkata 2020-01-09 20:54:10 IST
Asia/Aqtau 2020-01-09 20:24:10 +05
Asia/Dubai 2020-01-09 19:24:10 +04
Africa/Addis_Ababa 2020-01-09 18:24:10 EAT
Africa/Johannesburg 2020-01-09 17:24:10 SAST
Europe/Paris 2020-01-09 16:24:10 CET
Europe/London 2020-01-09 15:24:10 GMT
Atlantic/Cape_Verde 2020-01-09 14:24:10 -01
Atlantic/South_Georgia 2020-01-09 13:24:10 -02
America/Santiago 2020-01-09 12:24:10 -03
America/St_Johns 2020-01-09 11:54:10 NST
America/Halifax 2020-01-09 11:24:10 AST
US/Eastern 2020-01-09 10:24:10 EST
US/Central 2020-01-09 09:24:10 CST
US/Mountain 2020-01-09 08:24:10 MST
US/Pacific 2020-01-09 07:24:10 PST
US/Alaska 2020-01-09 06:24:10 AKST
Pacific/Honolulu 2020-01-09 05:24:10 HST
Pacific/Pago_Pago 2020-01-09 04:24:10 SST
FarWest+12 2020-01-09 03:24:10 FarWest
Time passes; it is now after midnight in Tokyo.
I use this, which is basically the same as the other suggestions, except it filters on specific zones you want to see:
#!/bin/sh
# Show date and time in other time zones
search=$1
zoneinfo=/usr/share/zoneinfo/posix/
format='%a %F %T'
find -L $zoneinfo -type f \
| grep -i "$search" \
| while read z
do
d=$(TZ=$z date +"$format")
printf "%-34s %23s\n" ${z#$zoneinfo} "$d"
done
Sample output:
$ /usr/local/bin/wdate bang
Africa/Bangui Fri 2009-03-06 11:04:24
Asia/Bangkok Fri 2009-03-06 17:04:24
Update:
On current systems with systemd
, there is timedatectl list-timezones
to replace searching through the file system to get the timezone names.
So a simpler version of that script could now be:
#!/bin/sh
# Show date and time in other time zones
search=$1
format='%a %F %T'
timedatectl list-timezones \
| grep -i "$search" \
| while read z
do
d=$(TZ=$z date +"$format")
printf "%-34s %23s\n" "$z" "$d"
done
Or a full version which falls back to find
if the timedatectl
command is not available :
#!/bin/sh
# Show date and time in other time zones
search=$1
zoneinfo=/usr/share/zoneinfo/posix/
format='%a %F %T'
if command -v timedatectl >/dev/null; then
tzlist=$(timedatectl list-timezones)
else
tzlist=$(find -L $zoneinfo -type f)
fi
grep -i "$search" <<< "$tzlist" \
| while read z
do
d=$(TZ=$z date +"$format")
printf "%-34s %23s\n" ${z#$zoneinfo} "$d"
done
There is ./cpython-2.7/Demo/curses/tclock.py that is a port of tclock.c
-- 1994 ASCII analog/digital clock for curses
, from ncurses-examples. Usage:
$ TZ=Europe/Paris python tclock.py
Here's video .
If you do still want to write it in Python, consider Pytz:
Their front page shows you many simple ways to accomplish what you're looking for.
That said, I'm sure if you spent a few minutes on Google you'd find tons of scripts, some that even launch graphical programs for *nix. The first list of results for "python world clock" seem to suggest this alone.
I created asimple shell script that you can call to print the location and date/time in that given location. Its logic at this moment in time:
TIME_ZONES="Europe/Amsterdam America/Los_Angeles Europe/Dublin"
OUTPUT=""
for loc in $TIME_ZONES; do
CITY=`echo $loc | sed 's/\// /g' | awk '{ print $2 }'`
CUR_TIME=`TZ=${loc} date | awk '{ print $2 " " $3 " " $5 }'`
TEMP=`awk -v l="$CITY" -v t="$CUR_TIME" 'BEGIN { print l "\t" t }'`
OUTPUT="${OUTPUT}\n${TEMP}"
done
echo $OUTPUT | column -t
Returns:
Amsterdam 1 Nov 01:03:30
Los_Angeles 31 Oct 17:03:30
Dublin 1 Nov 00:03:30
I like the script mivk provided. As I want to be able to specify multiple zones without regex, I adapted the script to use bash when I couldn't get bourne shell to deal with arrays. Anyway, enjoy and thanks for a great forum:
#!/usr/bin/env bash
# Show date and time in other time zones, with multiple args
elements=$@
zoneinfo=/usr/share/zoneinfo
format='%a %F %T'
for search in ${elements[@]}; do
find $zoneinfo -type f \
| grep -i "$search" \
| while read z
do
d=$(TZ=$z date +"$format")
printf "%-34s %23s\n" ${z#$zoneinfo} "$d"
done
done
Sample output:
/usr/local/bin/wdate Sydney Stockholm /Australia/Sydney Fri 2015-08-14 05:54:26 /Europe/Stockholm Thu 2015-08-13 21:54:26
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.