C Board  

Go Back   C Board > Platform Specific Boards > Windows Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 03-08-2010, 07:17 PM   #1
Registered User
 
Join Date: Dec 2009
Posts: 6
Convert a local time to a timezone's bias

I'm going mad here! I know this is simple, but I'm just not seeing what I'm doing wrong. I have a iCal data that has the timezone information and the start and end date time along with the timezone offset for from and to (TZOFFSETFROM and TZOFFSETTO). The start and end date time is in the time zone to whatever the iCal VTIMEZONE. I need to convert the start and end date time to the user's local time. Simple enough, just convert the start and end date time to UTC using iCal VTIMEZONE. Once the date time is in UTC, you can convert to the user's time zone.

If somebody can throw a book, URL, sample code at my way, I would appreciate it.

I'm throwing the code below out here, it's not all of it, but the crucial part of the code.

I'm having issues with certain time zones, such as Sydney and or Montevideo timezone can be one hour off when converting to CST. I just don't get it to what is going on.

Sydney TimeZone:
Code:
BEGIN:VTIMEZONE
TZID:AUS Eastern Standard Time
BEGIN:DAYLIGHT
RRULE:FREQ=3DYEARLY;BYDAY=3D1SU;BYMONTH=3D10
DTSTART:19701004T020000
TZOFFSETFROM:+1000
TZOFFSETTO:+1100
END:DAYLIGHT
BEGIN:STANDARD
RRULE:FREQ=3DYEARLY;BYDAY=3D1SU;BYMONTH=3D4
DTSTART:19700405T030000
TZOFFSETFROM:+1100
TZOFFSETTO:+1000
END:STANDARD
END:VTIMEZONE
Montevideo:
Code:
BEGIN:VTIMEZONE
TZID:Montevideo Standard Time
BEGIN:DAYLIGHT
RRULE:FREQ=3DYEARLY;BYDAY=3D1SU;BYMONTH=3D10
DTSTART:19701004T020000
TZOFFSETFROM:-0300
TZOFFSETTO:-0200
END:DAYLIGHT
BEGIN:STANDARD
RRULE:FREQ=3DYEARLY;BYDAY=3D2SU;BYMONTH=3D3
DTSTART:19700308T020000
TZOFFSETFROM:-0200
TZOFFSETTO:-0300
END:STANDARD
END:VTIMEZONE
Code:
bool iCal::InDaylightTime(FILETIME ft, TIME_ZONE_INFORMATION TZI)
{
    FILETIME    dlft;
    FILETIME    stft;
    SYSTEMTIME  st;

    FileTimeToSystemTime(&ft, &st);

    TZI.DaylightDate.wYear = st.wYear;
    TZI.StandardDate.wYear = st.wYear;

    SystemTimeToFileTime(&TZI.DaylightDate, &dlft);
    SystemTimeToFileTime(&TZI.StandardDate, &stft);

    if (::CompareFileTime(&ft, &dlft) >= 0 && ::CompareFileTime(&ft, &stft) <= 0) {
        return true;
    }

    return false;
}

FILETIME iCal::ConvertTime(const struct icaltimetype t)
{
    TIME_ZONE_INFORMATION m_TZI;
    unsigned __int64         Bias;
    LARGE_INTEGER           li;
    FILETIME                      FileTime = { 0 };

    UnixTimeToFileTime32(icaltime_as_timet(t), &FileTime);

    // Fill out m_TZI, TZOffsetToDaylight and TZOffsetToStandard
    GetTimeZoneInformationFromiCal();

    // WRONG - Beginning of incorrect calculation of the time
    if (InDaylightTime(FileTime, m_TZI)) {
        Bias = m_TZOffsetToDaylight;
    }
    else {
        Bias = m_TZOffsetToStandard;
    }
    // WRONG - End of incorrect calculation of the time

    if (Bias) {
        Bias = Bias * 10000000;
    }

    if (Bias) {
        li.LowPart = FileTime.dwLowDateTime;
        li.HighPart = FileTime.dwHighDateTime;
        li.QuadPart += Bias;

        FileTime.dwLowDateTime = li.LowPart;
        FileTime.dwHighDateTime = li.HighPart;
    }

    return FileTime;
}
NightCode is offline   Reply With Quote
Old 03-09-2010, 11:45 AM   #2
Registered User
 
Join Date: Dec 2009
Posts: 6
I figured out what I was doing wrong. I shouldn't have been checking to see if the time is within the timezone daylight time. I renamed "iCal::InDaylightTime" to "iCal::GetTimeZoneBias". iCal::GetTimeZoneBias check to see what the timezone standard and daylight time are to each other (is standard before or after daylight), depending on that is how I will test to see if the time is in daylight or not and from that return the time zone offset to convert the time to the correct UTC time.

Quite simple once I got my head wrapped around the timezones.

Code:
int iCal::GetTimeZoneBias(FILETIME ft, TIME_ZONE_INFORMATION TZI)
{
    FILETIME    dlft;
    FILETIME    stft;
    SYSTEMTIME  st;

    FileTimeToSystemTime(&ft, &st);

    TZI.DaylightDate.wYear = st.wYear;
    TZI.StandardDate.wYear = st.wYear;

    SystemTimeToFileTime(&TZI.DaylightDate, &dlft);
    SystemTimeToFileTime(&TZI.StandardDate, &stft);

    if (::CompareFileTime(&dlft, &stft) > 0) {
        if (::CompareFileTime(&ft, &stft) >= 0 && ::CompareFileTime(&ft, &dlft) <= 0) {
            return m_TZOffsetToStandard;
        }

        return m_TZOffsetToDaylight;
    }

    if (::CompareFileTime(&ft, &dlft) >= 0 && ::CompareFileTime(&ft, &stft) <= 0) {
        return m_TZOffsetToDaylight;
    }

    return m_TZOffsetToStandard;
}
NightCode is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
time synchronization problem freeindy C Programming 1 04-19-2007 06:25 AM
Is this really true or it's just science fiction? Nutshell A Brief History of Cprogramming.com 145 04-09-2002 06:17 PM
time class Unregistered C++ Programming 1 12-11-2001 10:12 PM
File I/O convert Unregistered C++ Programming 1 10-03-2001 08:10 AM
relating date.... Prakash C Programming 3 09-19-2001 09:08 AM


All times are GMT -6. The time now is 12:06 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22