Thread: Convert a local time to a timezone's bias

  1. #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;
    }

  2. #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;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

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