OpenWrt Forum Archive

Topic: Setting time zone using UCI

The content of this topic has been archived on 15 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

I like to set the time zone using UCI and I've written a patch for this. What do you think about it?

This is a quick hack. A better way would be to select the location from a flat text file database.

Index: package/base-files/files/etc/config/system
===================================================================
--- package/base-files/files/etc/config/system  (revision 8090)
+++ package/base-files/files/etc/config/system  (working copy)
@@ -1,2 +1,3 @@
 config system
        option hostname OpenWrt
+       option timezone ''
Index: package/base-files/files/etc/init.d/boot
===================================================================
--- package/base-files/files/etc/init.d/boot    (revision 8090)
+++ package/base-files/files/etc/init.d/boot    (working copy)
@@ -10,6 +10,11 @@
        config_get hostname "$cfg" hostname
        echo "${hostname:-OpenWrt}" > /proc/sys/kernel/hostname
 
+       [ ! -f /etc/TZ ] && {
+               config_get timezone "$cfg" timezone
+               echo "$timezone" > /etc/TZ
+       }
+
        config_get conloglevel "$cfg" conloglevel
        [ -n "$conloglevel" ] && dmesg -n "$conloglevel"

(Last edited by forum2006 on 21 Jul 2007, 14:32)

The timezone fields are defined in at least two packages (samba, openntpd) and are expected to reside in the /etc/config/timezone.
The timezone config is designed to contain both the POSIX TZ string and the reference to the Olson's database. The reference is important because we are able to synchronize the POSIX TZ string with the regular updates of the Olson's database.
Your quick hack breaks the timezone handling in samba, openntpd and webif2 . Is it intentional?

Because you have consulted the implementation with mbm and nbd, the following comments are addressed to all:

Why have we the possibility to define different configs for different things?
I do not see any benefit in having all definitions in the system config.
Moreover I think that the /etc/init.d/boot should be splitted into smaller parts with the different time to run. Some of them should run at boot, some of them could be (re)started/stopped in the runtime. We need to run some scripts before the coldplug of network interfaces. It was probably the reason of squashing in the timezone initialization.

I wonder why are init scripts in OpenWrt so shoddy.
There is no reason not to define available configuration switches in the configuration file (again no system config but the application's config) and design the init sript for as many switches as possible. This way the user can set the option in the config by the uci command and restart the service. Why must every user edit (for many of them cryptic) init script? Why is not there for example the status command by default?

Just for fun, what are the main 7 differences between starting the klogd/syslogd in OpenWrt https://dev.openwrt.org/browser/trunk/p … nit.d/boot and in X-Wrt https://svn.berlios.de/svnroot/repos/xw … t.d/syslog?

BTW: I designed the matrixtunnel init script lately (with the openvpn implementation in mind), see http://pastebin.ca/627678 (the paste has a limited time of availability). The script will not run in the current trunk because it needs the rc scripts modification. I wonder if it is possible to insert it somewhere into the /etc/init.d/boot and /etc/config/system. lol

Well, here is what I ended up with. I've already packaged it. The reson for writing this script is, that the user don't have to deal with the userunfriendly posixtz format.

The problem is that I can't figure out how to write the posixtz value to /etc/config/timezone using a UCI function. Probably writing to config files with a UCI function isn't implemented (I didn't get an answer from nbd on IRC) sad config_set doesn't seem to work. If anyone know how to fix this reply here.

Listing the timezones with '/etc/init.d/timezone list' and setting it with 'uci set timezone.cfg1.zoneinfo=Europe/Berlin' and writing to /etc/TZ with '/etc/init.d/timezone start' works well.

- timezone.patch (on pastebin)

timezone.patch

Index: packages/utils/timezone/files/usr/lib/timezones.csv
===================================================================
--- packages/utils/timezone/files/usr/lib/timezones.csv    (revision 0)
+++ packages/utils/timezone/files/usr/lib/timezones.csv    (revision 0)
@@ -0,0 +1,114 @@
+#timezone group    timezone cities    timezone config string    zoneinfo
+#revision: 2007f
+#  it is not exact for the "cities list" but it enables to remember 
+#  the selection and to synchronize TZs with the standard zoneinfo
+Australia    Melbourne,Canberra,Sydney    EST-10EST,M10.5.0,M3.5.0/3    Australia/Melbourne
+Australia    Perth    WST-8    Australia/Perth    Perth
+Australia    Brisbane    EST-10    Australia/Brisbane
+Australia    Adelaide    CST-9:30CST,M10.5.0,M3.5.0/3    Australia/Adelaide
+Australia    Darwin    CST-9:30    Australia/Darwin
+Australia    Hobart    EST-10EST,M10.1.0,M3.5.0/3    Australia/Hobart
+
+Europe    Amsterdam,Netherlands    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Amsterdam
+Europe    Athens,Greece    EET-2EEST,M3.5.0/3,M10.5.0/4    Europe/Athens
+Europe    Berlin,Germany    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Berlin
+Europe    Brussels,Belgium    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Brussels
+Europe    Bratislava,Slovakia    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Bratislava
+Europe    Budapest,Hungary    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Budapest
+Europe    Copenhagen,Denmark    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Copenhagen
+Europe    Dublin,Ireland    GMT0IST,M3.5.0/1,M10.5.0    Europe/Dublin
+Europe    Helsinki,Finland    EET-2EEST,M3.5.0/3,M10.5.0/4    Europe/Helsinki
+Europe    Kyiv,Ukraine    EET-2EEST,M3.5.0/3,M10.5.0/4    Europe/Kiev
+Europe    Lisbon,Portugal    WET0WEST,M3.5.0/1,M10.5.0    Europe/Lisbon
+Europe    London,GreatBritain    GMT0BST,M3.5.0/1,M10.5.0    Europe/London
+Europe    Madrid,Spain    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Madrid
+Europe    Oslo,Norway    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Oslo
+Europe    Paris,France    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Paris
+Europe    Prague,CzechRepublic    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Prague
+Europe    Roma,Italy    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Rome
+Europe    Moscow,Russia    MSK-3MSD,M3.5.0,M10.5.0/3    Europe/Moscow
+Europe    Stockholm,Sweden    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Stockholm
+Europe    Zurich,Switzerland    CET-1CEST,M3.5.0,M10.5.0/3    Europe/Zurich
+
+New Zealand    Auckland, Wellington    NZST-12NZDT,M10.1.0,M3.3.0/3    Pacific/Auckland
+
+USA & Canada    Hawaii Time    HST10    Pacific/Honolulu
+USA & Canada    Alaska Time    AKST9AKDT,M3.2.0,M11.1.0    America/Anchorage
+USA & Canada    Pacific Time    PST8PDT,M3.2.0,M11.1.0    America/Los_Angeles
+USA & Canada    Mountain Time    MST7MDT,M3.2.0,M11.1.0    America/Denver
+USA & Canada    Mountain Time (Arizona, no DST)    MST7    America/Phoenix
+USA & Canada    Central Time    CST6CDT,M3.2.0,M11.1.0    America/Chicago
+USA & Canada    Eastern Time    EST5EDT,M3.2.0,M11.1.0    America/New_York
+
+Atlantic    Bermuda    AST4ADT,M3.2.0,M11.1.0    Atlantic/Bermuda
+
+Asia (UTC+1)    Anadyr    ANAT-12ANAST,M3.5.0,M10.5.0/3    Asia/Anadyr
+
+Asia (UTC+2)    Amman    EET-2EEST,M3.5.4/0,M10.5.5/1    Asia/Amman
+Asia (UTC+2)    Beirut    EET-2EEST,M3.5.0/0,M10.5.0/0    Asia/Beirut
+Asia (UTC+2)    Damascus    EET-2EEST,J91/0,J274/0    Asia/Damascus
+Asia (UTC+2)    Gaza    EET-2EEST,J91/0,M10.3.5/0    Asia/Gaza
+Asia (UTC+2)    Jerusalem    GMT-2    Asia/Jerusalem
+Asia (UTC+2)    Nicosia    EET-2EEST,M3.5.0/3,M10.5.0/4    Asia/Nicosia
+
+Asia (UTC+3)    Aden    AST-3    Asia/Aden
+Asia (UTC+3)    Baghdad    AST-3ADT,J91/3,J274/4    Asia/Baghdad
+Asia (UTC+3)    Bahrain    AST-3    Asia/Bahrain
+Asia (UTC+3)    Kuwait    AST-3    Asia/Kuwait
+Asia (UTC+3)    Qatar    AST-3    Asia/Qatar
+Asia (UTC+3)    Riyadh    AST-3    Asia/Riyadh
+
+Asia (UTC+3:30)    Tehran    IRST-3:30    Asia/Tehran
+
+Asia (UTC+4)    Baku    AZT-4AZST,M3.5.0/4,M10.5.0/5    Asia/Baku
+Asia (UTC+4)    Dubai    GST-4    Asia/Dubai
+Asia (UTC+4)    Muscat    GST-4    Asia/Muscat
+Asia (UTC+4)    Tbilisi    GET-4    Asia/Tbilisi
+Asia (UTC+4)    Yerevan    AMT-4AMST,M3.5.0,M10.5.0/3    Asia/Yerevan
+
+Asia (UTC+4:30)    Kabul    AFT-4:30    Asia/Kabul
+
+Asia (UTC+5)    Aqtobe    AQTT-5    Asia/Aqtobe
+Asia (UTC+5)    Ashgabat    TMT-5    Asia/Ashgabat
+Asia (UTC+5)    Dushanbe    TJT-5    Asia/Dushanbe
+Asia (UTC+5)    Karachi    PKT-5    Asia/Karachi
+Asia (UTC+5)    Oral    ORAT-5    Asia/Oral
+Asia (UTC+5)    Samarkand    UZT-5    Asia/Samarkand
+Asia (UTC+5)    Tashkent    UZT-5    Asia/Tashkent
+Asia (UTC+5)    Yekaterinburg    YEKT-5YEKST,M3.5.0,M10.5.0/3    Asia/Yekaterinburg
+
+Asia (UTC+5:30)    Calcutta    IST-5:30    Asia/Calcutta
+Asia (UTC+5:30)    Colombo    IST-5:30    Asia/Colombo
+
+Asia (UTC+6)    Almaty    ALMT-6    Asia/Almaty
+Asia (UTC+6)    Bishkek    KGT-6    Asia/Bishkek
+Asia (UTC+6)    Dhaka    BDT-6    Asia/Dhaka
+Asia (UTC+6)    Novosibirsk    NOVT-6NOVST,M3.5.0,M10.5.0/3    Asia/Novosibirsk
+Asia (UTC+6)    Omsk    OMST-6OMSST,M3.5.0,M10.5.0/3    Asia/Omsk
+Asia (UTC+6)    Qyzylorda    QYZT-6    Asia/Qyzylorda
+Asia (UTC+6)    Thimphu    BTT-6    Asia/Thimphu
+
+Asia (UTC+7)    Jakarta    WIT-7    Asia/Jakarta
+Asia (UTC+7)    Bangkok    ICT-7    Asia/Bangkok
+Asia (UTC+7)    Vientiane    ICT-7    Asia/Vientiane
+Asia (UTC+7)    Phnom Penh    ICT-7    Asia/Phnom_Penh
+
+Asia (UTC+8)    Chongqing    CST-8    Asia/Chongqing
+Asia (UTC+8)    Hong Kong    HKT-8    Asia/Hong_Kong
+Asia (UTC+8)    Shanghai    CST-8    Asia/Shanghai
+Asia (UTC+8)    Singapore    SGT-8    Asia/Singapore
+Asia (UTC+8)    Urumqi    CST-8    Asia/Urumqi
+Asia (UTC+8)    Taiwan    CST-8    Asia/Taipei
+Asia (UTC+8)    Ulaanbaatar    ULAT-8    Asia/Ulaanbaatar
+
+Asia (UTC+9)    Dili    TLT-9    Asia/Dili
+Asia (UTC+9)    Jayapura    EIT-9    Asia/Jayapura
+Asia (UTC+9)    Pyongyang    KST-9    Asia/Pyongyang
+Asia (UTC+9)    Seoul    KST-9    Asia/Seoul
+Asia (UTC+9)    Tokyo    JST-9    Asia/Tokyo
+Asia (UTC+9)    Yakutsk    YAKT-9YAKST,M3.5.0,M10.5.0/3    Asia/Yakutsk
+
+Central and South America    Sao Paulo,Brazil    BRT3BRST,M11.1.0/0,M2.5.0/0    America/Sao_Paulo
+Central and South America    Argentina    ART3    America/Argentina/Buenos_Aires
+# no offense, just something in the center
+Central and South America    Central America (no DST)    CST6    America/Guatemala
Index: packages/utils/timezone/files/etc/config/timezone
===================================================================
--- packages/utils/timezone/files/etc/config/timezone    (revision 0)
+++ packages/utils/timezone/files/etc/config/timezone    (revision 0)
@@ -0,0 +1,4 @@
+config timezone
+    option posixtz  ''
+    option zoneinfo ''
+    option etctz    '/etc/TZ'
Index: packages/utils/timezone/files/etc/init.d/timezone
===================================================================
--- packages/utils/timezone/files/etc/init.d/timezone    (revision 0)
+++ packages/utils/timezone/files/etc/init.d/timezone    (revision 0)
@@ -0,0 +1,56 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+START=11
+
+EXTRA_COMMANDS="list"
+EXTRA_HELP="        list    Lists available time zones"
+
+TIMEZONE_TABLE=/usr/lib/timezones.csv
+
+get_posix_timezone () {
+    awk -v timezoneinfo="$zoneinfo" 'BEGIN { FS = "    " }
+        /^(#.*)?$/ { next }
+        { list_timezone = $4; if ( list_timezone == timezoneinfo ) { print $3 } }
+        END { }' < $TIMEZONE_TABLE 2>/dev/null
+}
+
+list_available_timezones () {
+    awk 'BEGIN { FS = "    "; last_group="" }
+        /^(#.*)?$/ { next }
+        $1 != last_group { last_group=$1; print "\n" $1 }
+        { list_timezone = $4; print "  " list_timezone }
+        END { }' < $TIMEZONE_TABLE 2>/dev/null
+}
+
+start_service () {
+    local section="$1"
+    config_get posixtz  "$section" posixtz
+    config_get zoneinfo "$section" zoneinfo
+    config_get etctz    "$section" etctz
+
+    if [ ! -h "$etctz" ]; then 
+        ln -sf /tmp/TZ "$etctz"
+    fi
+    [ -n "$zoneinfo" ] && get_posix_timezone "$zoneinfo" > "$etctz" || echo "UTC+0" > "$etctz"
+
+    # config_set
+    # posixtz=get_posix_timezone "$zoneinfo"
+
+    config_set "timezone" "posixtz" "foobar"
+}
+
+start () {
+    config_load "timezone"
+    config_foreach start_service timezone
+}
+
+restart () {
+    start
+}
+
+list () {
+    echo "Available time zones"
+    echo "--------------------"
+
+    list_available_timezones
+}
Index: packages/utils/timezone/Makefile
===================================================================
--- packages/utils/timezone/Makefile    (revision 0)
+++ packages/utils/timezone/Makefile    (revision 0)
@@ -0,0 +1,43 @@
+# 
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id$
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=timezone
+PKG_VERSION:=1.0
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/timezone
+  SECTION:=utils
+  CATEGORY:=Base system
+  TITLE:=Configure the time zone
+endef
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/timezone/install
+    $(INSTALL_DIR) $(1)/etc/config
+    $(INSTALL_CONF) ./files/etc/config/timezone $(1)/etc/config
+    $(INSTALL_DIR) $(1)/etc/init.d
+    $(INSTALL_BIN) ./files/etc/init.d/timezone $(1)/etc/init.d
+    $(INSTALL_DIR) $(1)/usr/lib
+    $(INSTALL_DATA) ./files/usr/lib/timezones.csv $(1)/usr/lib
+endef
+
+$(eval $(call BuildPackage,timezone))

(Last edited by forum2006 on 22 Jul 2007, 13:17)

I am glad that you have returned to the timezone config. smile
It is a long time I did the full database in White Russian (http://forum.x-wrt.org/index.php/topic,96.0.html)
I am sorry, i have not had enough time to work on it.

For now I have not checked thoroughly your scripts but they look well. I think that it is the right way.
Listing of the zones is neat idea although it could take a longer time with the full database.
The package should be equipped with the tzselect script (the distributed does not work with busybox's ash).
I would also attach the postinst script to refresh the information in the config with the package upgrade.

The main problem in the solution is the data source. It would require to generate it off the buildroot (like i do it in webif2).
Therefore I have extracted the necessary part and have tried to put it into some fashion for you to include it into the package.

forum2006 wrote:

The problem is that I can't figure out how to write the posixtz value to /etc/config/timezone using a UCI function. Probably writing to config files with a UCI function isn't implemented (I didn't get an answer from nbd on IRC) sad config_set doesn't seem to work. If anyone know how to fix this reply here.

There is no problem writing to configs using uci functions. The variable must be either enclosed in the quotes or properly escaped.

Take a look at it and consider its inclusion:
Makefile

#
# Copyright (C) 2007 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#

include $(TOPDIR)/rules.mk

PKG_NAME:=timezone
PKG_VERSION:=2007f
PKG_RELEASE:=1

PKG_SOURCE_URL:=ftp://elsie.nci.nih.gov/pub \
    ftp://munnari.oz.au/pub/oldtz
PKG_SOURCE_CODE:=tzcode$(PKG_VERSION).tar.gz
PKG_MD5SUM_CODE:=fdfa8b941827a33e7a43aaf039ea9b67
PKG_SOURCE_DATA:=tzdata$(PKG_VERSION).tar.gz
PKG_MD5SUM_DATA:=799ca289ee9e2f22ce6e3f9fb9c5f847
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

define Package/timezone
  SECTION:=base
  CATEGORY:=Base system
  TITLE:=POSIX time zone information data and scripts
  DESCRIPTION:=\
    The package contains necessary data to select, setup and maintain \\\
    the POSIX TZ environment variable. The TZ information is extracted \\\
    from the public-domain Olson's time zone database.
  URL:=http://www.twinsun.com/tz/tz-link.htm
endef

$(DL_DIR)/$(PKG_SOURCE_CODE):
    $(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(PKG_SOURCE_CODE)" "$(PKG_MD5SUM_CODE)" $(PKG_SOURCE_URL)

$(DL_DIR)/$(PKG_SOURCE_DATA):
    $(SCRIPT_DIR)/download.pl "$(DL_DIR)" "$(PKG_SOURCE_DATA)" "$(PKG_MD5SUM_DATA)" $(PKG_SOURCE_URL)

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    gzip -dc $(DL_DIR)/$(PKG_SOURCE_CODE) | $(TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
    gzip -dc $(DL_DIR)/$(PKG_SOURCE_DATA) | $(TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
endef

define Build/Compile
    LC_ALL=C $(MAKE) -C $(PKG_BUILD_DIR) \
        CC=$(HOSTCC) \
        CFLAGS="-DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DNOSOLAR" \
        AWK=AWK \
        SDATA="" \
        TOPDIR=$(PKG_BUILD_DIR)/tzdir install
    LC_ALL=C ./make_zoneinfo.sh "$(PKG_BUILD_DIR)/tzdir/etc" "$(PKG_BUILD_DIR)" "$(PKG_VERSION)"
endef

define Package/timezone/install
    $(INSTALL_DIR) $(1)/usr/share/zoneinfo
    $(CP) -a $(PKG_BUILD_DIR)/{iso3166,zone,zoneinfo}.tab $(1)/usr/share/zoneinfo/
    $(CP) -a ./files/* $(1)/
endef

$(eval $(call BuildPackage,timezone))

and make_zoneinfo.sh (it must reside in the same directory as Makefile):

#!/bin/sh
# Create POSIX time zone information file
# Parameters
# 1 - zoneinfo directory
# 2 - target directory
# 3 - source versioninfo

if [ $# != 3 ]; then
    echo "$0: missing parameters"
    exit 1
fi

ZONEINFOROOT="$1"
TARGETDIR="$2"
ZONESLST="$2/zoneinfo.tab"
TMPLST="$ZONESLST.tmp"
SOURCEVER="$3"

# make target directory
mkdir -p "$TARGETDIR"

cat > "$ZONESLST" << EOF
# @(#)zoneinfo.tab
# data source version: $SOURCEVER
#
# Zone names with POSIX TZ strings
# The file content is an extract from the Olson's time zone database.
# It shares its public-domain status.
#
# This file contains a table with the following columns:
# 1. Zone name used in value of modern TZ environment variable.
# 2. City (may contain spaces)
# 3. POSIX zone string used in value of POSIX TZ environment variable.
# 4. UTC offset (+#, 0, -#).
#
# Columns are separated by a single tab.
# The table is sorted alphabetically by continent and city for
# easy city lookup.
#
# Lines beginning with '#' are comments.
#
#TZ    CITY    POSIX    OFFSET
EOF

touch "$TMPLST"

pushd "$ZONEINFOROOT/zoneinfo-posix"
# use only selected
for zonetab in $(grep -v "^#" ../zoneinfo/zone.tab |awk -F"\t" '{ print $3 }')
do
    TZTAIL=$(tail -1 "$zonetab")
    if [ "$TZTAIL" != "" ]; then
        # split
        ZONE1LPATH="${zonetab%%/*}"
        ZONEFILE="${zonetab##*/}"
        ZONECITY="${ZONEFILE//_/ }"
        # offset
        OFFTMP=$(echo "$TZTAIL" |cut -d ',' -f 1 |sed 's/^[[:alpha:]]\{1,\}//' |sed 's/[[:alpha:]].*//')
        OFFSET="+$OFFTMP"
        OFFSET="${OFFSET/+-/-}"
        OFFSET="${OFFSET/+0/0}"
        # sort first
        echo -e "${ZONE1LPATH}/${ZONEFILE}\t${zonetab}\t${ZONECITY}\t${TZTAIL}\t${OFFSET}" >>"$TMPLST"
    fi
done
popd

sort -k 1 "$TMPLST" |cut -f2,3,4,5 >>"$ZONESLST"
rm -f "$TMPLST"

The discussion might have continued from here.