Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Windows Mobile: SetSystemTime and DST, Einstein’s Relativity Theory?

, 8 Oct 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
SetSystemTime and DST, better disable DST before using SetSystemTime

Wow, as I first saw this issue, I thought I was facing Einstein’s Relativity Theory.

The issue is simple to explain:

  • The WinMo device has a local time and date within DST.
  • You use SetSystemTime to set a new system time and date outside the DST frame.
  • The local time changes, but DST is still applied!

In concrete example:

GetTimeZoneInformation:
 DaylightSaving-Time:

Bias -60  Daylight-Name: W  Daylight-Bias: -60 Standard-Name: W  Standard-Bias: 0
Standard-Date: 00/10/05 03:00:00, Daylight-Date: 00/03/05 02:00:00

1. Set time inside DST +++++++++++
+++++++++++ TstSetTime ++++++++++++
SetSystemTime:  2010/09/21 10:32:00
GetLocalTime:   2010/09/21 12:32:00
GetSystemTime:  2010/09/21 10:32:00

------------ TstSetTime ------------
2. Set time outside DST ----------
+++++++++++ TstSetTime ++++++++++++
SetSystemTime:  2010/10/31 01:50:00
GetLocalTime:   2010/10/31 03:50:00
GetSystemTime:  2010/10/31 01:50:00

As you can see, local time is 2 hours of, although the data/time is outside DST. You can also see that the device is in GMT+1 time zone.

Ah, you say this is a known issue. OK, let's do it the Microsoft way and Sleep() and set system time again:

3. SLEEP...
4. Set time outside DST 2nd CALL ----------
+++++++++++ TstSetTime ++++++++++++
SetSystemTime:  2010/10/31 01:50:00
GetLocalTime:   2010/10/31 02:50:00
GetSystemTime:  2010/10/31 01:50:00

You are right, now the local time is correct.

Ok, not clear but a workaround. Now go on and set time back into DST:

------------ TstSetTime ------------
5. Set time back inside DST +++++++++++
+++++++++++ TstSetTime ++++++++++++
SetSystemTime:  2010/09/21 10:32:00
GetLocalTime:   2010/09/21 11:32:00
GetSystemTime:  2010/09/21 10:32:00

Again a fault. This time DST is not applied although the date is within DST frame.

Doing the same in Compact Framework is worse and you will only get valid results with disabled DST.

The best workaround is to disable DST BEFORE you change the system time and then restore DST after changing the system time.

.NET Code Snippets

private DateTime startDateTime = DateTime.Parse("2010/9/24 11:42:00");

[DllImport("coredll.dll", SetLastError = true)]
static extern Int32 GetLastError();

[DllImport("coredll.dll", SetLastError = true)]
static extern bool SetSystemTime(ref SYSTEMTIME time);
[DllImport("coredll.dll", SetLastError = true)]
static extern void GetSystemTime(out SYSTEMTIME lpSystemTime);

[DllImport("coredll.dll")]
static extern bool SetTimeZoneInformation([In] 
	ref TIME_ZONE_INFORMATION lpTimeZoneInformation);
[DllImport("coredll.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation
	(out TIME_ZONE_INFORMATION lpTimeZoneInformation);

private const int TIME_ZONE_ID_UNKNOWN = 0;
private const int TIME_ZONE_ID_STANDARD = 1;
private const int TIME_ZONE_ID_DAYLIGHT = 2;

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
    public short wYear;
    public short wMonth;
    public short wDayOfWeek;
    public short wDay;
    public short wHour;
    public short wMinute;
    public short wSecond;
    public short wMilliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TIME_ZONE_INFORMATION
{
    public int bias;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string standardName;
    public SYSTEMTIME standardDate;
    public int standardBias;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
    public string daylightName;
    public SYSTEMTIME daylightDate;
    public int daylightBias;
}
...
private bool disableDST(TIME_ZONE_INFORMATION tzi){
    //set wMonth in standardDate to zero
    SYSTEMTIME stStd;
    stStd=tzi.standardDate;
    stStd.wMonth=0;
    //set wMonth in daylightDate to zero
    SYSTEMTIME stDST;
    stDST=tzi.daylightDate;
    stDST.wMonth=0;
    
    tzi.daylightDate=stDST;
    tzi.standardDate=stStd;
    bool bRes = SetTimeZoneInformation(ref tzi);
    if (bRes)
        addText("*** Disabling DST OK***");
    else
        addText("*** Disabling DST failed***");
    return bRes;
}

Possibly good information for all those who do TimeSync with a server.

<!-- Social Bookmarks BEGIN --> <!-- Social Bookmarks END -->

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

hjgode

Germany Germany
No Biography provided

Comments and Discussions

 
QuestionNot work on Window mobile 6.5 Pinmemberljnhnn312-Sep-11 22:42 
AnswerRe: Not work on Window mobile 6.5 Pinmemberhjgode13-Sep-11 4:57 
GeneralRe: Not work on Window mobile 6.5 Pinmemberljnhnn313-Sep-11 7:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 8 Oct 2010
Article Copyright 2010 by hjgode
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid