Daylight Saving Time (DST) Handling in Linux
This document (3655154) is provided subject to the disclaimer at the end of this document.
Environment
SUSE Linux Enterprise Server 10
SUSE Linux Enterprise Desktop 10
Situation
Resolution
This document provides background information on how Daylight Savings Time is handled under Linux. For information on specific updates relating to recent changes in DST start and end dates in various regions, refer to the "Related TIDs" section under "Additional Notes" below.
System time and hardware clock
The Linux kernel maintains a system time. This time is initialized at boot time using the hardware clock(also known as real time clock, RTC, BIOS clock or CMOS clock). As the hardware clock does not provide information as to whether it is kept in UTC or in local time, this needs to be configured explicitly, in YaST -> System -> /etc/sysconfig Editor -> System -> Environment -> Clock -> HWCLOCK.
Linux changing to and from DST
Linux will change to and from DST when the HWCLOCK setting is set to `-u', i.e. when the hardware clock is set to UTC (which is closely related to GMT), regardless of whether Linux was running at the time DST is entered or left.
When the HWCLOCK setting is set to `--localtime', Linux will not adjust the time, operating under the assumption that your system may be a dual boot system at that time and that the other OS takes care of the DST switch. If that was not the case, the DST change needs to be made manually.
Regular applications
The local time as seen by regular applications under Linux is based on two things:
- The system time
- The TZ (for timezone) environment variable
Brazil/East Sun Feb 18 02:00:00 2007 UTC = Sat Feb 17 23:00:00 2007 BRT isdst=0 gmtoff=-10800
Whether DST is honoured in a particular region and if so, what its start and end dates are, can change over time. The timezone package for SUSE Linux Enterprise products is updated regularly to reflect regulatory DST changes.
Java applications
The Java Runtime Environment (JRE) includes its own, slightly different, timezone database. Thus, when the timezone definitions change, the JRE should be updated as well.
Additional Information
To address the time zone changes that have not been updated in currently available updates, the following manual process can be used to update systems immediately.
Notes about this process:
- These "manual" changes WILL be lost if updates are applied to the system that do not contain the corrected timezone information. The timezone information is included in the timezone package. Applying older versions of this or related packages should be followed by re-applying these "manual" changes.
- These "manual" changes do not require a reboot of the system. Some applications may have cached information in memory and will not re-read these changes. A reboot may be useful to ensure all applications have read the updated timezone data.
- Download the most recent time zone data file (at the time of writing, tzdata2007b.tar.gz) from ftp://ftp.iana.org/tz/releases/ . Updates to this data file have the year and release letter updated.
- Copy the file to a temporary workspace of your choice on the Linux system.
- Extract the data with the following command:
tar xvfz tzdata2007b.tar.gz
- Apply the updates for the region(s) of interest the system's time zone data through the zic command. E.g., to update the North American data, run
zic northamerica
- Relink the new time zone names with the old time zone names that were just updated with the following command: (See the Additional Notes below for a workaround to possible error(s) in this step.)
zic backward
- Verify that the updates are applied correctly with the following command
zdump -v timezoneofinterest | grep yearofintereste.gzdump -v Canada/Mountain | grep 2007The output from the previous step should look similar to this:
Canada/Mountain Sun Mar 11 08:59:59 2007 UTC = Sun Mar 11 01:59:59 2007 MST isdst=0 gmtoff=-25200
Canada/Mountain Sun Mar 11 09:00:00 2007 UTC = Sun Mar 11 02:00:00 2007 MST isdst=1 gmtoff=-21600
Canada/Mountain Sun Nov 4 07:59:59 2007 UTC = Sun Nov 4 01:59:59 2007 MST isdst=1 gmtoff=-21600
Canada/Mountain Sun Nov 4 08:00:00 2007 UTC = Sun Nov 4 02:00:00 2007 MST isdst=0 gmtoff=-25200 - Relink the localtime setting (in /etc/localtime) with the corrected timezone information using the following command
zic -l timezonenamee.g.zic -l Canada/Mountain
Executing zic backward may return errors if other time zone data is not recent enough. One option would be to update those time zone as well in the same manner as noted in step 4 after identifying the specific time zones involved.
A workaround in this situation is to extract only the time zones from backward that need to be re-linked following execution of step 4 above. In this case that would be the time zones that are listed in the northamerica file. The following steps can be substitued for step 5 above:
zic backward.america
Validating DST changes for Java
To validate whether DST changes occur on the correct date for Java code, the following test code can be used:
import java.text.*;
class testdst {
public static void main(String args[]){
if((args.length != 4)){
if((args.length == 1) && args[0].equals("-list")){
System.out.println("Available time zones are:");
String[] list = TimeZone.getAvailableIDs();
int i;
for(i = 0; i < list.length; i++)
System.out.println(list[i]);
} else {
System.out.println("Usage testdst ");
System.out.println("or testdst -list");
}
System.exit(1);
}
TimeZone t = TimeZone.getTimeZone(args[0]);
System.out.println("Using time zone " + t.getDisplayName());
System.out.println("Use parameter -list to get a list of available time zones");
GregorianCalendar cal = new GregorianCalendar(t);
int year = new Integer(args[1]).intValue() - 1900;
int month = new Integer(args[2]).intValue() - 1;
int day = new Integer(args[3]).intValue();
Date d = new Date(year, month, day, 12, 0);
System.out.println("Testing date " + DateFormat.getDateInstance().format(d));
cal.setTime(d);
int offset_day = cal.get(Calendar.DST_OFFSET);
Date d2 = new Date(year, month, day-1, 12, 0);
cal.setTime(d2);
int offset_preday = cal.get(Calendar.DST_OFFSET);
if(offset_day == offset_preday)
System.out.println("There was no change in the daylight saving time offset");
else
System.out.println("The daylight saving time offset was changed");
System.exit(0);
}
}
Please refer to the documentation of the Java SDK and runtime environment for details on how to compile and run it.
Further reading
For general information about DST, please refer to Wikipedia,Daylight saving time, http://en.wikipedia.org/wiki/Daylight_saving_time.
For information about the zoneinfo database which is the basis for the timezone information in the timezone package, refer to Wikipedia, Zoneinfo, http://en.wikipedia.org/wiki/Zoneinfo.
For more information about the relationship between the hardware clock and the system time maintained by the Linux kernel, refer to the hwclock(8) manual page.
Disclaimer
This Support Knowledgebase provides a valuable tool for SUSE customers and parties interested in our products and solutions to acquire information, ideas and learn from one another. Materials are provided for informational, personal or non-commercial use within your organization and are presented "AS IS" WITHOUT WARRANTY OF ANY KIND.
- Document ID:3655154
- Creation Date: 31-Mar-2008
- Modified Date:24-Feb-2021
-
- SUSE Linux Enterprise Desktop
- SUSE Linux Enterprise Server
- SUSE Linux Enterprise Software Development Kit
For questions or concerns with the SUSE Knowledgebase please contact: tidfeedback[at]suse.com