NSLU2-Linux
view · edit · print · history

The time zone info files from linksys or unslung firmware is not up-to-date enough. In particular, US 2007 daylight saving time change is not covered.

Thanks to the inspiration from the old method (grey'd out below), here is a new one which will allow the GUI to work.

  --tlhackque

Use the following script

 
#!/bin/sh
#
# Get the latest rules
#
ipkg update
ipkg install tz
#
# Backup linksys TZ directory & create a new one with links to tz package's rules
#
if [ ! -e /usr/zoneinfo.linksys ]; then
    mv /usr/zoneinfo /usr/zoneinfo.linksys
fi
if [ -d /usr/zoneinfo ]; then
    rm -rf /usr/zoneinfo/*
else
    mkdir /usr/zoneinfo
fi
#
# The left side of this map was created from Set_TimeZone's list of timezones
# The right size was created automagically by searching the tz package for the
# corresponding rule.  A few manual edits removed duplicate names.
#
MAP=`cat <<EOF
Kwajalein|Pacific/Kwajalein
Midway|Pacific/Midway
Honolulu|Pacific/Honolulu
Anchorage|America/Anchorage
Tijuana|America/Tijuana
Phoenix|America/Phoenix
Mountain|US/Mountain
Central|US/Central
Mexico_City|America/Mexico_City
Regina|America/Regina
Lima|America/Lima
Eastern|US/Eastern
East-Indiana|US/East-Indiana
Atlantic|Atlantic
Caracas|America/Caracas
Santiago|America/Santiago
St_Johns|America/St_Johns
Buenos_Aires|America/Argentina/Buenos_Aires
South_Georgia|Atlantic/South_Georgia
Azores|Atlantic/Azores
Casablanca|Africa/Casablanca
Dublin|Europe/Dublin
Berlin|Europe/Berlin
Belgrade|Europe/Belgrade
Brussels|Europe/Brussels
Sarajevo|Europe/Sarajevo
Athens|Europe/Athens
Bucharest|Europe/Bucharest
Cairo|Africa/Cairo
Harare|Africa/Harare
Helsinki|Europe/Helsinki
Baghdad|Asia/Baghdad
Moscow|Europe/Moscow
Tehran|Asia/Tehran
Muscat|Asia/Muscat
Baku|Asia/Baku
Kabul|Asia/Kabul
Yekaterinburg|Asia/Yekaterinburg
Karachi|Asia/Karachi
Calcutta|Asia/Calcutta
Almaty|Asia/Almaty
Colombo|Asia/Colombo
Bangkok|Asia/Bangkok
Hong_Kong|Asia/Hong_Kong
Perth|Australia/Perth
Singapore|Asia/Singapore
Taipei|Asia/Taipei
Tokyo|Asia/Tokyo
Seoul|Asia/Seoul
Yakutsk|Asia/Yakutsk
Adelaide|Australia/Adelaide
Darwin|Australia/Darwin
Brisbane|Australia/Brisbane
Sydney|Australia/Sydney
Guam|Pacific/Guam
Hobart|Australia/Hobart
Vladivostok|Asia/Vladivostok
Magadan|Asia/Magadan
Auckland|Pacific/Auckland
Fiji|Pacific/Fiji
EOF
`
#
# For each linksys-supported TZ, create a softlink to the corresponding ipk rule
#
for z in $MAP ; do
    LN=`echo "$z" | sed -e's+^\(.*\)|\(.*\)$+/opt/share/zoneinfo/\2 /usr/zoneinfo/\1+'`
    ln -sf $LN
done
#
# Find current timezone per linksys GUI
#
tzone=`grep 'time_zone=' /etc/CGI_ds.conf | sed -e's|^.*=\(.*\)$|\1|'`
#
# Convert to its proper name
#
tzone=`expr $tzone + 1`
#
tzone=`sed -n -e"${tzone}p" <<EOF
Kwajalein
Midway
Honolulu
Anchorage
Tijuana
Phoenix
Mountain
Central
Mexico_City
Regina
Lima
Eastern
East-Indiana
Atlantic
Caracas
Santiago
St_Johns
Buenos_Aires
South_Georgia
Azores
Casablanca
Dublin
Berlin
Belgrade
Brussels
Sarajevo
Athens
Bucharest
Cairo
Harare
Helsinki
Baghdad
Moscow
Tehran
Muscat
Baku
Kabul
Yekaterinburg
Karachi
Calcutta
Almaty
Colombo
Bangkok
Hong_Kong
Perth
Singapore
Taipei
Tokyo
Seoul
Yakutsk
Adelaide
Darwin
Brisbane
Sydney
Guam
Hobart
Vladivostok
Magadan
Auckland
Fiji
EOF
`
#
# Copy the new rule over localtime (just what Set_TimeZone would do)
#
cp -f /usr/zoneinfo/$tzone /usr/local/localtime 2>/dev/null
#
# Create the conventional links in /usr/share
#
if [ ! -e /usr/share ]; then
    mkdir /usr/share
fi
ln -sf /opt/share/zoneinfo /usr/share/zoneinfo
ln -sf /opt/share/zoneinfo-leaps /usr/share/zoneinfo-leaps
ln -sf /opt/share/zoneinfo-posix /usr/share/zoneinfo-posix

# ******************************
exit
# ******************************
#
# To create the MAP, we ran strings on Set_TimeZone and extracted
# this list
#
LIST=`cat <<EOF
Kwajalein
Midway
Honolulu
Anchorage
Tijuana
Phoenix
Mountain
Central
Mexico_City
Regina
Lima
Eastern
East-Indiana
Atlantic
Caracas
Santiago
St_Johns
Buenos_Aires
South_Georgia
Azores
Casablanca
Dublin
Berlin
Belgrade
Brussels
Sarajevo
Athens
Bucharest
Cairo
Harare
Helsinki
Baghdad
Moscow
Tehran
Muscat
Baku
Kabul
Yekaterinburg
Karachi
Calcutta
Almaty
Colombo
Bangkok
Hong_Kong
Perth
Singapore
Taipei
Tokyo
Seoul
Yakutsk
Adelaide
Darwin
Brisbane
Sydney
Guam
Hobart
Vladivostok
Magadan
Auckland
Fiji
EOF
`
#
# Here, we look for the matching zone in the real database
#
for z in $LIST ; do
    echo "$z|`find /opt/share/zoneinfo/ -name "$z" | sed -e's|^/opt/share/zoneinfo/||'`"
done
#
# Manual edits are required to remove a few alises.
#

Original Method

To correct that, follow these steps.

  • Install the new timezone data files into /opt/share/zoneinfo:
 # ipkg update
 # ipkg install tz
  • Put the timezone data file installed by the Linksys web gui:
 # MY_TZ=America/Los_Angeles    (change to the appropriate time zone)
 # mv /usr/local/localtime /usr/local/localtime.bak
 # cp /opt/share/zoneinfo/$MY_TZ /usr/local/localtime
  • Arrange to ensure that the Linksys tools won't overwrite your update at boot time:
    How to do this depends if you already have a diversion script for the Linksys rc.rstimezone startup script. Just list the contents of /unslung -- if rc.rstimezone is not listed, then create one as follows:
 # if [ ! -f /unslung/rc.rstimezone ] ; then
 >  echo '#!/bin/sh'            >> /unslung/rc.rstimezone
 >  echo '/usr/sbin/hwclock'    >> /unslung/rc.rstimezone
 >  echo '/usr/sbin/hwclock -s' >> /unslung/rc.rstimezone
 >  echo 'return 0'             >> /unslung/rc.rstimezone
 >  chmod 755 /unslung/rc.rstimezone
 > fi
If a diversion script does exist, then you must make sure that the Linksys Set_TimeZone utility is not run, or it will change your timezone back at each boot. This command will comment out the Set_TimeZone command if present:
 # [ -f /unslung/rc.rstimezone ] && /bin/sed -i -e '/^\/usr\/sbin\/Set_TimeZone/s|^|#|' /unslung/rc.rstimezone
Warning: if you have a pre-existing rc.rstimezone script, you must ensure that it performs at least the "hwclock -s" (aka hwclock --hctosys) action, and that it exits with a "return 0". If yours exits with a "return 1", then it will cause the Linksys script to execute, and overwrite your timezone change.
  • Write the updated current time back to the hardware clock:
 # hwclock --systohc

Testing

I tested it with the following, and it shows PDT, which is working.

 $ date --date="Mar 11 15:00:00 UTC 2007"
 Sun Mar 11 08:00:00 PDT 2007

Once the TZ package has been installed, you can use this to see if the time changes will take effect on the correct dates (substitute the current year if not 2007):

 # zdump -v /etc/localtime | grep 2007

See also debian wiki for how to test.

After updating /usr/local/localtime, please avoid using the timezone part of linksys web UI. Selecting a timezone with the linksys web UI might overwrite /usr/local/localtime with the old zoneinfo.

In order for other timezone info to work with /opt/bin/date, you also need to

 # ln -s /opt/share/zoneinfo* /usr/share

You can use the tzwatch ipk to test by setting a couple of timezones in ~/.tzlist .


Background info:

It is a feature of glibc to translate machine hardware time to the time zone you want. The date command uses this libc service. You can specify your localtime in a couple of ways:

1. TZ environment variable 2. /etc/localtime file in compiled zoneinfo format (zoneinfo file contains things like gmt offset, when does DST start/end for which year, what is the DST gmt offset, etc.)

On unslung, /etc/localtime is a link to /usr/local/localtime. The tz package provides up-to-date compiled zoneinfo files for all the timezones, and the key step is just "cp the-right-zoneinfo /usr/local/localtime".

For detail see http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html , especially the following paragraph:

If the TZ environment variable does not have a value, the operation chooses a time zone by default. In the GNU C library, the default time zone is like the specification `TZ=:/etc/localtime' (or `TZ=:/usr/local/etc/localtime', depending on how GNU C library was configured; see Installation). Other C libraries use their own rule for choosing the default time zone, so there is little we can say about them.


See also http://www.linuxdevices.com/news/NS6300956032.html

view · edit · print · history · Last edited by tlhackque.
Based on work by tlhackque, mwester, Jack, and BrianZhou.
Originally by BrianZhou.
Page last modified on March 08, 2008, at 02:49 AM