TIME CONVERSION BUG

// TimeConstructionBug.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "ATLComTime.h"

 

int _tmain(int argc, _TCHAR* argv[])

{

COleDateTime a(2006, 12, 1, 17, 0, 0);

SYSTEMTIME b;

a.GetAsSystemTime(b);

FILETIME c;

::SystemTimeToFileTime(&b, &c);

COleDateTime d(c);

CString startTime(a.Format());

CString endTime(d.Format());

printf("StartTime %s, EndTime %s\n", (LPCTSTR)startTime, (LPCTSTR)endTime);

return 0;

}

I compiled the above C++ code (minimum to show the possible bug) using Visual Studio 2005 as a console application using ATL, MFC and MultiByte strings.

You may be surprised at the result, on my machine I got the following...

StartTime 01/12/2006 17:00:00, EndTime 01/12/2006 18:00:00

In theory both start and end times should be 17:00 after conversion.

This bug is causing a "show stopper" for my development after converting over to the new compiler.   The code appears to work just fine with the old compiler - am I doing something wrong

Ian.



Answer this question

TIME CONVERSION BUG

  • rileyt

    Ok, specifically the BUG is in Construction of an OleDateTime using a FILETIME structure.   This construction seems to be affected by the date and time of the machines local system clock.

     

    When the date of the local system clock on my machine is in Winter Time (here in the UK this is GMT+0), I run the example code, and it works perfectly.

     

    If I change the date of the local system clock to one in Summer Time (for the UK this is GMT +1) and run the example code, an hour is added to the time during construction of the local variable "d" as an OleDateTime using the value of "c" which is a FILETIME structure.

     

    I'm pretty sure this should NOT happen, and DID NOT happen in the older version of the compiler.   As Kian pointed out OleDateTimes should not take daylight saving into account - nor should their construction (in isolation) be affected by the local system clock.

     

    Why should the time shown by my local system clock affect my example code

     

    Can Microsoft please confirm that this is a bug - US Time Zone's move into Summer time This Week and I'm worried that code may break.

     

    Ian.


  • GeoffCarr

    Thanks.

     

    I've also tried compiling this using Version 6.0 of the compiler (and libraries) and I am surprised that the behaviour is consistant.

     

    However, there is nothing in the documentation regarding OleDateTimes and FileTimes to suggest that a conversion should take place subject to the date shown by the local system clock.

     

    I added the following line to my example to check that the time would not change if the OleDateTime were constructed from a SystemTime - and it does not.

     

    COleDateTime e(b);

     

     

    I am deeply confused.


  • tom025

    Thanks Ayman, I've followed your instructions and noted the 'feature'.

    The most likely outcome for the short term is that someone will have to instruct the technical authors to accurately describe this constructors behaviour rather than correct the actual behaviour.

    Ian.

    [Thanks for your additional input Kian, I think the issue is well understood now. The "feature" is present in the COleDateTime Construction using FILETIMES - daylight saving is applied with respect to the local system clock as opposed to the actual value contained in the FILETIME structure. My proposed work around is valid i.e. avoid using the FILETIME constructor to construct a COleDateTime for anything other than a "real-time" time taken directly from the local system clock (which is always stored in UTC)].


  • oprah

    Interestingly the very latest documentation on COleDateTime constructors for using FILETIME contains the following caveat:-

     

    A FILETIME structure to be converted to a date/time value and copied into the new COleDateTime object. Note that FILETIME uses Universal Coordinated Time (UTC), so if you pass a local time in the structure, your results will be incorrect. See File Times in the Platform SDK for more information

     

    The documentation in Version 6.0 of the compiler did not contain the additional Note.

     

    I still think that the behaviour is a bug.   If I declare...

     

    INT a = 5;

    DOUBLE b = (DOUBLE )a;

     

    Then I don't expect 'b' to contain 6 just because I am in summer time.


  • Just-A-Nerd

    dear Litey

    so sory for bieng late to answer.

    i'm not a member of microsoft.

    i gess i understood where the problem comes from see the code below:

    #include "afxwin.h"
    #include "ATLComTime.h"
    int _tmain(int argc, _TCHAR* argv[])
    {
    COleDateTime a(2006, 12, 1, 17, 0, 0);
    SYSTEMTIME b;
    a.GetAsSystemTime(b); // b=a succesfully
    FILETIME c;
    ::SystemTimeToFileTime(&b, &c); // c!=b[ ]
    AfxMessageBox( CTime(b).Format("%H:%M:%S") ); // b=a=17:00:00
    AfxMessageBox( COleDateTime(b).Format() ); // b=a=17:00:00
    AfxMessageBox( CTime(c).Format("%H:%M:%S") ); // c!=a , c=17:00:00+daylight saving + time diffrence from uk
    AfxMessageBox( COleDateTime(c).Format("%H:%M:%S") ); //c!=a , c=17:00:00+daylight saving + time diffrence from uk
    return 0;
    }

    Acording to this text, the problem might come from SYSTEMTIME <==> FILETIME conversions.

    i will be seeking to solve this problem ...


  • Mikey77

    I know this may be a daft attempt at an explanation, but we're now 1 hour ahead after introducing daylight saving on Sunday. Is this simply the result of a rounding error within the new compiler, some dodgy TimeZone bug, or me going mad
  • Wilhelm

    Please log the issue at http://lab.msdn.microsoft.com/productfeedback/default.aspx so that the lib team can take a look.

    Thanks in advance for taking the time to report the problem!

    Thanks,
    Ayman Shoukry
    VC++ Team


  • Ryo44453

    Read the msdn help search for COleDateTime. it says that this data type does not support the daylight saving time.
  • Vinutha DS

    And finally...

    The workaround for this is to convert the FILETIME back to a SYSTEMTIME (in which NO CONVERSION occurs i.e. the time still remains 17:00 reguardless of the system clock) and then construct the OleDateTime from the SystemTime.

    The COleDateTime FILETIME constructor therefore contains a bug. Even the latest Microsoft Documentation is misleading (to say the least). The behaviour of this constructor should in no way be influenced by the value of the local system clock.


  • RVNL

    i think the SystemTimeToFileTime function has a bug that converts the UTC to local time. that's why your old compiler could compile it good and it's not mentioned in msdn help for the function.


  • mikey4865

    Kian, please read the code carefully, I'm not attempting a time zone conversion here, I am convinced that this is a BUG in the compiler libraries where a time zone conversion is being erroneously applied.

    My code simply performs a sequence of constructions starting with a time set at 17:00 hours.

    The construction begins with an OleDateTime, transforms this to a System Time, then from a System Time to a FileTime, and from a FileTime back to an OleDateTime.

     

    Why does the time change at all    The answer is that it SHOULD NOT.   In any representation this time should remain 17:00 hours.

     

    Kian, do you work for Microsoft - is this an official reply


  • Justin Souders

    i think the conversion works like this in the code below:

    #include "afxwin.h"

    #include "ATLComTime.h"

    void _tmain(void)

    {

    COleDateTime o(2006, 12, 1, 17, 0, 0);

    SYSTEMTIME s;

    o.GetAsSystemTime(s);

    FILETIME f;

    ::SystemTimeToFileTime(&s, &f);

    LocalFileTimeToFileTime(&f,&f);

    AfxMessageBox( COleDateTime(f).Format("%H:%M:%S") );

    }

    coledatetime is converted to systemtime normally. but systemtime when converted to filetime, a conversion to local time occures! then the local filetime is converted back to utc time and then converted to coledatetime successfully!

    but in your code the local time stored in f (FILETIME) was directly converted to coledatetime with no converting back from local time to universal time.

    msdn siad that if you store a local time in file time, you may not pass it to the coledatetime contructor.

    as a summery the system time is converted to local time and then  copied to f in the SystemTimeToFileTime(&s, &f); command

    i'm not sure with what i siad. if system time is converted to local time then why msdn hasn't mentioned that in http://msdn.microsoft.com/library/default.asp url=/library/en-us/sysinfo/base/systemtimetofiletime.asp

     

    i'm looking ahead for your idias.


  • Hariharasuthan

    We discovered the same problem recently. Thanks for posting your problem here. It was helpful in determining what the cause was. I also found this page on MSDN:

    http://msdn2.microsoft.com/en-us/library/1yy4h318(VS.80).aspx

    At the bottom is a note that says this:

    FILETIME is in UTC, so the copy constructor for FILETIME (and also the FILETIME operator=), depending on the version of Visual Studio will either convert from UTC to local time, or not. Here is a quick summary of which versions do what:

    VS6: always converts to local time
    VS.NET (7): initial release does not convert. SP2 and above do convert
    VS2003 .NET (7.1): initial relase does not convert SP1 will
    VS2005 (8.0): always converts to local time


  • Dedicated Ameteur

    Ian,

    You may want to report this problem in the MSDN Product Feedback Center (http://lab.msdn.microsoft.com/productfeedback/default.aspx)

    Michael



  • TIME CONVERSION BUG