Solved

Given an arbitrary UTC time and an arbitrary time zone, how do I know if the time uses daylight savings time?

Posted on 2008-10-24
9
1,624 Views
Last Modified: 2013-11-20
I need to take an arbitrary date and time in UTC format and then figure out what that time was in a specific time zone.

Here are some examples of the data that we'll have to deal with:
   Translate March 28, 2001, 5 PM UTC to the central time zone
   Figure out Nov 4, 2007, 12 PM UTC to  the eastern time  zone
   Figure out Jan 1, 2009, 1 AM UTC to  the mountain time zone

Let's take the March 28, 2001 example first.  In 2001, the United States laws specified that daylight savings time did not begin until the first Sunday of April.  Starting in 2007, daylight saving time now starts on the second Sunday in March.  So depending on what rules you use, March 25 might or might not require daylight saving time.

Unfortunately, I'm not sure how to address this problem from within C++.  Vista and Windows 2008 have functions like GetDynamicTimeZoneInformation() and GetTimeZoneInformationForYear(), but I can't use them in older versions of Windows.  The closest function that XP seems to provide is GetTimeZoneInformation(), but this is limited to looking up time zone rules for the current calendar year.

I *could* try to code the logic manually, but what if legislation changes in the near future?  Then anyone who statically links to my library will get incorrect time stamps.

Any tips on what I can do to fix this problem?

Thanks!
0
Comment
Question by:TomPro
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 19

Expert Comment

by:LordOfPorts
ID: 22799889
The SystemTimeToTzSpecificLocalTime function http://msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx should provide a solution and it is available from Windows 2000 onwards. There is a number of examples for using it including e.g. http://weseetips.com/2008/05/28/how-to-convert-local-system-time-to-utc-or-gmt/

If the legislature changes the start date of the daylight savings time a patch would be released as the last time, that should take care of it.
0
 
LVL 19

Expert Comment

by:LordOfPorts
ID: 22799954
...here is one more example related to the function that might be useful: http://www.codeproject.com/KB/cpp/TimeZoneConverter.aspx
0
 
LVL 1

Author Comment

by:TomPro
ID: 22800297
LordOfPorts,

It's interesting that SystemTimeToTzSpecificLocalTime() is supported by Windows 2000--in my local MSDN documentation it doesn't say that, but sure enough the online documentation says that it is.

I'll run a few tests later this evening to confirm, then if everything works I'll award the points.

Thanks!
0
Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

 
LVL 1

Author Comment

by:TomPro
ID: 22826608
The plot thickens...

SystemTimeToTzSpecificLocalTime() apppears to work correctly on Windows XP, but not on Windows Server 2000 or Windows Server 2003.

Here's an example of a test case that's failing:

UTC time, in 100 nanosecond units:
128068740000000000

Expected Central Time answer:
2006-11-01T11:00:00.000-6:00

Results from XP:
2006-11-01T11:00:00.000-6:00

Results from Windows 2003 Server and 2000 Server:
2006-11-01T12:00:00.000-5:00

In 2006 (prior to the DST law changes brought into effect in 2007), DST in the United States ended on the last Sunday in October.  So on November 1, 2006, I think the clocks should have been on GMT-6:00,  not GMT-5:00.  So it looks like XP is correct and Windows 2000 / 2003 are incorrect.

This behavior shows up in the following code (error checking removed for simplicity).  Any ideas what might be happening?

Note:  All test systems are running in the Central Time (US & Canada) zone, and are set with accurate system time for the current time zone.

Thanks!


int 100nsUTCToLocalISO(__int64 time100ns, char *retTime, int retTimeSize)
{
int rstatus = 0;
FILETIME utcFileTime;
FILETIME localFileTime;
__int64 local100ns;
SYSTEMTIME sTime_UTC;
SYSTEMTIME sTime_LOC;
 
memcpy(&utcFileTime, &time100ns, sizeof(utcFileTime));
 
// convert the file time to UTC system time
FileTimeToSystemTime(&utcFileTime, &sTime_UTC);
 
// convert from UTC to local time
// THIS IS WHERE XP AND 2000 / 2003 BEHAVE DIFFERENTLY
SystemTimeToTzSpecificLocalTime(NULL, &sTime_UTC, &sTime_LOC);
 
// get the FILETIME for the local time
SystemTimeToFileTime(&sTime_LOC, &localFileTime);
 
// ...
// Write XML ISO timestamp in local time zone to retTime buffer
// ...
 
return rstatus;
}

Open in new window

0
 
LVL 19

Expert Comment

by:LordOfPorts
ID: 22827079
As the first step just to confirm are the patches http://support.microsoft.com/gp/dst_prodlist installed on the machines running Windows 2000 and 2003?

Second item is the call to the SystemTimeToTzSpecificLocalTime above whereby the first argument, the time zone information structure reference, is NULL which makes the function use the currently active time zone information; from reading the comprehensive MSDN article at http://support.microsoft.com/kb/932955 , specifically the "Local time conversion in Windows" section it appears that this can indeed introduce historical inaccuracies because of the changes to the DST so you indeed do have an issue when it comes to identifying the correct offset related the years.
0
 
LVL 19

Accepted Solution

by:
LordOfPorts earned 250 total points
ID: 22827156
...sorry, I submitted prior to completing the post. From researching the issue the best conclusion I could make is that you would indeed have to write an algorithm that based on the year retrieves the information about DST settings, e.g. in the registry under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\ you will find a listing of the settings, per attached screenshot notice the Central Standard Time time zone has entries for 2006 and 2007, after retrieving the information from the registry you would populate an instance of a TIME_ZONE_INFORMATION http://msdn.microsoft.com/en-us/library/ms725481(VS.85).aspx structure with the information for that particular year and pass it as the first argument to the SystemTimeToTzSpecificLocalTime function.

I located few threads that discuss this approach and have sample code however it is rather complex unfortunately:

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/ca9ed00a-39b0-4956-b052-54eb9e1a06d8/
http://www.eggheadcafe.com/software/aspnet/31656478/get-current-time-in-diffe.aspx
http://vbnet.mvps.org/index.html?code/locale/timezoneforecast.htm
TimeZones.png
0
 
LVL 1

Author Comment

by:TomPro
ID: 22827198
The Windows 2003 system has the 951072 v2 patch, which looks like the latest one.  I haven't looked at the Windows 2000 system yet.

The line that you pointed out from KB 932955 is interesting--but I'm not sure why the time translation would work in XP but not in 2000.
0
 
LVL 1

Author Comment

by:TomPro
ID: 22827615
LordOfPorts,

Thanks for the excellent answers.  I'm awarding points now.


0
 
LVL 1

Author Closing Comment

by:TomPro
ID: 31509809
You did a great job explaining a very complicated facet of Windows time-keeping.  Thanks for the great work.
0

Featured Post

Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
computer science syllabus 3 118
Create a path if not exists 7 128
OLD CPUs 12 132
How to increment counter variables in ANSI  C (Not C# or C++). 9 74
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

710 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question