Time Zones, tz Database, and Linux

alias now='date --iso-8601=seconds'
alias utc='date -u +"%Y-%m-%dT%H:%M:%S"'
$ now
2022-06-26T18:40:30+03:00
$ utc
2022-06-26T16:40:39

Time zones

Time zones and Linux

$ pacman -Qs tzdata
local/tzdata 2022a-1
Sources for time zone and daylight saving time data
$ sudo ln -sf /usr/share/zoneinfo/Europe/vilnius /etc/localtime
#!/usr/bin/env bashLOCALTIME_PATH=/etc/localtime
ZONEINFO_PATH=/usr/share/zoneinfo
get_timezone() {
realpath $LOCALTIME_PATH | rev | cut -d'/' -f1,2 | rev
}
get_timezones() {
local region="$1"
find $ZONEINFO_PATH/$region/* | rev | cut -d'/' -f1,2 | rev
}
get_regions() {
find $ZONEINFO_PATH/ -maxdepth 1 -type d | rev | cut -d'/' -f1,2 | rev | sed 's/zoneinfo\///;/^[[:space:]]*$/d'
}
set_timezone() {
local new_timezone_path="$1"
ln -sf "$ZONEINFO_PATH/$new_timezone_path" $LOCALTIME_PATH
}
print_help() {
cat<<END
timezone [OPTIONS]
OPTIONS:
-a <region> get all timezone in a region, e.g. Europe
-c get current timezone
-s <timezone> new timezone, e.g. Europe/Tallinn
-r get all regions
-h print this help
END
}
while getopts "cs:ha:r" opt; do
case $opt in
a) get_timezones "$OPTARG" ;;
c) get_timezone ;;
h) print_help ;;
s) set_timezone "$OPTARG" ;;
r) get_regions ;;
*) print_help ;;
esac
done
[ -z "$1" ] && print_helpexit 0
$ zdump -v Europe/Brussels | head -10
Europe/Brussels -9223372036854775808 (gmtime failed) = -9223372036854775808 (localtime failed)
Europe/Brussels -67768040609741851 (gmtime failed) = -67768040609741851 (localtime failed)
Europe/Brussels -67768040609741850 (gmtime failed) = Thu Jan 1 00:00:00 -2147481748 LMT isdst=0 gmtoff=1050
Europe/Brussels -67768040609740801 (gmtime failed) = Thu Jan 1 00:17:29 -2147481748 LMT isdst=0 gmtoff=1050
Europe/Brussels Thu Jan 1 00:00:00 -2147481748 UT = Thu Jan 1 00:17:30 -2147481748 LMT isdst=0 gmtoff=1050
Europe/Brussels Wed Dec 31 23:42:29 1879 UT = Wed Dec 31 23:59:59 1879 LMT isdst=0 gmtoff=1050
Europe/Brussels Wed Dec 31 23:42:30 1879 UT = Thu Jan 1 00:00:00 1880 BMT isdst=0 gmtoff=1050
Europe/Brussels Sat Apr 30 23:59:59 1892 UT = Sun May 1 00:17:29 1892 BMT isdst=0 gmtoff=1050
Europe/Brussels Sun May 1 00:00:00 1892 UT = Sun May 1 00:00:00 1892 WET isdst=0 gmtoff=0
Europe/Brussels Sat Nov 7 23:59:59 1914 UT = Sat Nov 7 23:59:59 1914 WET isdst=0 gmtoff=0

tz database

$ git clone https://github.com/eggert/tz
$ cd tz/
$ git grep -n Vilnius
NEWS:2150: Europe/Kaliningrad and Europe/Vilnius changed from +03/+04 to
europe:1918:# (Europe/Vilnius) was changed.
europe:1943:Zone Europe/Vilnius 1:41:16 - LMT 1880
tzfile.h:110:/* This must be at least 17 for Europe/Samara and Europe/Vilnius. */
zone.tab:256:LT +5441+02519 Europe/Vilnius
zone1970.tab:213:LT +5441+02519 Europe/Vilnius
# Zone NAME  STDOFF RULES FORMAT [UNTIL]
Zone Europe/Vilnius 1:41:16 - LMT 1880
1:24:00 - WMT 1917 # Warsaw Mean Time
1:35:36 - KMT 1919 Oct 10 # Kaunas Mean Time
1:00 - CET 1920 Jul 12
2:00 - EET 1920 Oct 9
1:00 - CET 1940 Aug 3
3:00 - MSK 1941 Jun 24
1:00 C-Eur CE%sT 1944 Aug
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
2:00 Russia EE%sT 1991 Sep 29 2:00s
2:00 C-Eur EE%sT 1998
2:00 - EET 1998 Mar 29 1:00u
1:00 EU CE%sT 1999 Oct 31 1:00u
2:00 - EET 2003 Jan 1
2:00 EU EE%sT
$ grep -P -B1 '^Rule[[:space:]]EU' europe 
# Rule NAME FROM TO - IN ON AT SAVE LETTER/S
Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S
Rule EU 1977 only - Sep lastSun 1:00u 0 -
Rule EU 1978 only - Oct 1 1:00u 0 -
Rule EU 1979 1995 - Sep lastSun 1:00u 0 -
Rule EU 1981 max - Mar lastSun 1:00u 1:00 S
Rule EU 1996 max - Oct lastSun 1:00u 0 -

Privacy considerations

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store