12

My system timezone is Asia/Tehran, and it has DST changes adjusts in Summer (spring forward) and fall back in Winter; however I do need to disable these DST adjustments and keep timezone always in UTC+3:30. how do I do that in Linux?

αғsнιη
  • 40,939
  • 15
  • 71
  • 114

1 Answers1

20

Part1: Update timeZone for the OS

From 22-September 2022 onwards, Iran will abolish DST and observe standard time year-round. The first official package with these updates are came in "tzdata2022b.tar.gz" package by IANA, therefore here is the way how to apply region Asia/Tehran timeZone updates from it.

  1. Download the package tzdata2022b.tar.gz and decompress it; see All Packages here if you want to get the latest package to apply.

    $ tar -xzvf tzdata2022b.tar.gz
    
  2. Compile to apply the updates for the region(s) of interest (Asia) the system's time zone data through the 'zic' (timezone compiler) command (you should be root/root-privileged user):

    # zic asia
    

    Note: the changes will be applied on the Asia/Tehran directly as well as other regions in Asia.

  3. Verify that the updates are applied correctly with the following command and DST is disabled (Note that after 'Wed Sep 21 23:59:59' (Fallback to +0330 as Iran Standard Time) and date afterwards no DST adjusts will be happened):

    # zdump -v -c2022,2029 Asia/Tehran Asia/Tehran -9223372036854775808 = NULL Asia/Tehran -9223372036854689408 = NULL Asia/Tehran Mon Mar 21 20:29:59 2022 UTC = Mon Mar 21 23:59:59 2022 +0330 isdst=0 Asia/Tehran Mon Mar 21 20:30:00 2022 UTC = Tue Mar 22 01:00:00 2022 +0430 isdst=1 Asia/Tehran Wed Sep 21 19:29:59 2022 UTC = Wed Sep 21 23:59:59 2022 +0430 isdst=1 Asia/Tehran Wed Sep 21 19:30:00 2022 UTC = Wed Sep 21 23:00:00 2022 +0330 isdst=0 Asia/Tehran 9223372036854689407 = NULL Asia/Tehran 9223372036854775807 = NULL

  4. Relink the localtime /etc/localtime with the corrected timeZone information using the following command:

    # zic -l Asia/Tehran
    
  5. Verify that date and hwclock are reporting correct date &time.


Below is the solution how to build and apply a specific country timeZone updates only (Asia/Tehran in this answer).
  1. Create a custom ZONE file called Tehran_timeZone and add below Zone information (Rules and Zone information each country can be found in the relevant region file in the tzdata2022b.tar.gz package):

    $ cat Tehran_timeZone
    # Rule  NAME    FROM    TO  -   IN  ON  AT  SAVE    LETTER/S
    Rule    Iran    1910    only    -   Jan  1  00:00   0   -
    Rule    Iran    1977    only    -   Mar 21  23:00   1:00    -
    Rule    Iran    1977    only    -   Oct 20  24:00   0   -
    Rule    Iran    1978    only    -   Mar 24  24:00   1:00    -
    Rule    Iran    1978    only    -   Aug  5  01:00   0   -
    Rule    Iran    1979    only    -   May 26  24:00   1:00    -
    Rule    Iran    1979    only    -   Sep 18  24:00   0   -
    Rule    Iran    1980    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    1980    only    -   Sep 22  24:00   0   -
    Rule    Iran    1991    only    -   May  2  24:00   1:00    -
    Rule    Iran    1992    1995    -   Mar 21  24:00   1:00    -
    Rule    Iran    1991    1995    -   Sep 21  24:00   0   -
    Rule    Iran    1996    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    1996    only    -   Sep 20  24:00   0   -
    Rule    Iran    1997    1999    -   Mar 21  24:00   1:00    -
    Rule    Iran    1997    1999    -   Sep 21  24:00   0   -
    Rule    Iran    2000    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2000    only    -   Sep 20  24:00   0   -
    Rule    Iran    2001    2003    -   Mar 21  24:00   1:00    -
    Rule    Iran    2001    2003    -   Sep 21  24:00   0   -
    Rule    Iran    2004    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2004    only    -   Sep 20  24:00   0   -
    Rule    Iran    2005    only    -   Mar 21  24:00   1:00    -
    Rule    Iran    2005    only    -   Sep 21  24:00   0   -
    Rule    Iran    2008    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2008    only    -   Sep 20  24:00   0   -
    Rule    Iran    2009    2011    -   Mar 21  24:00   1:00    -
    Rule    Iran    2009    2011    -   Sep 21  24:00   0   -
    Rule    Iran    2012    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2012    only    -   Sep 20  24:00   0   -
    Rule    Iran    2013    2015    -   Mar 21  24:00   1:00    -
    Rule    Iran    2013    2015    -   Sep 21  24:00   0   -
    Rule    Iran    2016    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2016    only    -   Sep 20  24:00   0   -
    Rule    Iran    2017    2019    -   Mar 21  24:00   1:00    -
    Rule    Iran    2017    2019    -   Sep 21  24:00   0   -
    Rule    Iran    2020    only    -   Mar 20  24:00   1:00    -
    Rule    Iran    2020    only    -   Sep 20  24:00   0   -
    Rule    Iran    2021    2022    -   Mar 21  24:00   1:00    -
    Rule    Iran    2021    2022    -   Sep 21  24:00   0   -
    
    # Zone  NAME        STDOFF  RULES   FORMAT  [UNTIL]
    Zone    Asia/Tehran 3:25:44 -   LMT 1916
                3:25:44 -   TMT 1935 Jun 13 # Tehran Mean Time
                3:30    Iran    +0330/+0430 1977 Oct 20 24:00
                4:00    Iran    +04/+05 1979
                3:30    Iran    +0330/+0430
    

    For more information about the config parameters, see the "man zic"

  2. Compile to apply the updates for the Asia/Tehran timeZone through the 'zic' command:

    $ zic Tehran_timeZone
    
  3. Relink the localtime /etc/localtime with the corrected timeZone information using the following command:

    # zic -l Asia/Tehran
    

Note: Depending on what Linux distribution are you using, you will need to reconfigure the ZONE for which system is using at startup (configure with tzdata-update or timedatectl set-timezone Asia/Tehran)

Note: User/shell level timeZone
The date command by default is using the same /etc/localtime when displaying date &time at user/shell level, however if variable TZ was set to something different, then it will read and apply the timeZone from that TZ variable, so you will need to either unset/delete it or set that to the current locatime TZ='Asia/Tehran' in the user level shell profiles; this is a command to find files which TZ variable might set in those files under user's home directories:

# find /home/ -maxdepth 2 -type f -exec grep -wH 'TZ' {} +

Note: You will need to update the same for the system-wide shell profiles.


Part2: Update timeZone for the Java-based applications (OpenJDK, OracleJDK, IBMJDK, etc)

  1. You have an updated timeZone file (https://data.iana.org/time-zones/releases/tzdata2022b.tar.gz)

  2. You need to download a Java-based compiler to compile the tzdata2022b.tar.gz file into Java compatible timezone; we used the open source ZIUpdater tool (Download from https://www.azul.com/products/open-source-tools/ziupdater-time-zone-tool/)

  3. Run below command to compile the timezone from the tzdata2022b.tar.gz package using ziupdater.jar tool:

    $JAVA_HOME/bin/java -jar ziupdater.jar -l tzdata2022b.tar.gz
    
  4. Done. The ziupdater.jar tool will generate tzdb.dat (original location for the tzdb.dat is $JAVA_HOME/lib/tzdb.dat) for JDKv8+ and and for JDKv7 and earlier it will genrate a directory named zi (original location is $JAVA_HOME/lib/zi/*) with all updated timezone files and you only need to replace the old ones with the new ones (you might want to take a backup first from old timezones)

  5. Application restart probably is required.

Notes:
After patching timezone, once you need to:

  1. Unset the TZ environment variable and restart sshd service.
  2. Restart the cron/crond service.
  3. Restart the rsyslog or any other syslog service your server have it running.
  4. Some applications and specifically DBs might not use neither of OS or JDK timeZone files, and for that you need to refer its documentation for how-do-do that separately.
αғsнιη
  • 40,939
  • 15
  • 71
  • 114
  • i did update and compile timezone, but php timezone has no difference – Katerou22 Apr 08 '23 at 05:10
  • @Katerou22 for the php, you need to patch/install its own timezonedb extension separately. see [https://pecl.php.net/package/timezonedb]. if you don't have that extension already installed, then you need to update the php.ini file to tell the php which that extension is exist after you have installed it. then restart the php to take affect the new timezonedb changes. – αғsнιη Apr 10 '23 at 06:17