Excel Vba: Utc time to local
От: Esef Украина  
Дата: 13.10.10 16:01
Оценка:
Киньте кто нибудь правильную функцию для ковертирвания времени в VBA c формата UTC в локальный. Функция должна правильно учитывать смену зимнего/летнего времени.
Весь гугл излазил, немогу найти. Все как сговорились делают одну ошибку, например здесь:
http://www.vbusers.com/code/codeget.asp?PostID=1&ThreadID=632
берут текущее смещание относительно utc и прибавляют к дате которуе надо переконвертировать
Т.е. если мы имеем дату 01.01.2010 12:00 то результат будет разным в зависимости от текущего времени. Летом мы ее сконвертируем
01.01.2010 14:00, зимой в 01.01.2010 13:00
а надо что бы 01.01.2010 12:00 всегда конвертировалась в 01.01.2010 13:00 а
01.06.2010 12:00 в 01.06.2010 14:00.
Re: Excel Vba: Utc time to local
От: ZAMUNDA Земля для жалоб и предложений
Дата: 13.10.10 20:44
Оценка:
Здравствуйте, Esef, Вы писали:
E>Киньте кто нибудь правильную функцию для ковертирвания времени в VBA c формата UTC в локальный. Функция должна правильно учитывать смену зимнего/летнего времени.
Потерял, вот восстановил по памяти... вроде оно.
Option Explicit

Public Declare Function SystemTimeToVariantTime _
               Lib "oleaut32.dll" (ByRef lpSystemTime As SYSTEMTIME, _
                                   ByRef pvTime As Date) _
                                   As Long

Public Declare Function VariantTimeToSystemTime _
               Lib "oleaut32.dll" (ByVal vtime As Date, _
                                   ByRef lpSystemTime As SYSTEMTIME) _
                                   As Long


Public Declare Function GetTimeZoneInformation _
               Lib "Kernel32.dll" (ByRef lpTimeZoneInformation As TIME_ZONE_INFORMATION) _
                                   As Long

Public Declare Function TzSpecificLocalTimeToSystemTime _
               Lib "Kernel32.dll" (ByRef lpTimeZone As TIME_ZONE_INFORMATION, _
                                   ByRef lpLocalTime As SYSTEMTIME, _
                                   ByRef lpUniversalTime As SYSTEMTIME) _
                                   As Long

Public Declare Function SystemTimeToTzSpecificLocalTime _
               Lib "Kernel32.dll" (ByRef lpTimeZone As TIME_ZONE_INFORMATION, _
                                   ByRef lpUniversalTime As SYSTEMTIME, _
                                   ByRef lpLocalTime As SYSTEMTIME) _
                                   As Long


Public Const SYSTEMTIME_SIZE As Long = 16&

Public Type SYSTEMTIME
    wYear As Integer
    wMonth As Integer
    wDayOfWeek As Integer
    wDay As Integer
    wHour As Integer
    wMinute As Integer
    wSecond As Integer
    wMilliseconds As Integer
End Type

Public Type TIME_ZONE_INFORMATION
    Bias As Long
    StandardName(31) As Integer
    StandardDate As SYSTEMTIME
    StandardBias As Long
    DaylightName(31) As Integer
    DaylightDate As SYSTEMTIME
    DaylightBias As Long
End Type

Private mudtTZI As TIME_ZONE_INFORMATION

Public Sub Main()
    Dim lng As Long
    lng = GetTimeZoneInformation(mudtTZI)
    
    ' Не помню чему равен TIME_ZONE_ID_INVALID, т.е. не уверен что -1 тут
    If lng = -1& Then
        Err.Raise Err.LastDllError Or &H80070000
    End If
    
    Dim dtm As Date
    
    dtm = #1/1/2010 12:00:00 PM#
    
    Debug.Print "UTC2Local: " & dtm & " --> "; TimeUTC2Local(dtm)
    Debug.Print "Local2UTC: " & dtm & " --> "; TimeLocal2UTC(dtm)
    
    dtm = #6/1/2010 12:00:00 PM#
        
    Debug.Print "UTC2Local: " & dtm & " --> "; TimeUTC2Local(dtm)
    Debug.Print "Local2UTC: " & dtm & " --> "; TimeLocal2UTC(dtm)
End Sub

Public Function TimeUTC2Local( _
    ByVal dtmUTC_I As Date) _
    As Date
    
    Dim dtmLocal As Date
    Dim udtUTC As SYSTEMTIME
    Dim udtLocal As SYSTEMTIME
    Dim lng As Long
    
    lng = VariantTimeToSystemTime(dtmUTC_I, udtUTC)
    
    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::VariantTimeToSystemTime"
    End If
    
    lng = SystemTimeToTzSpecificLocalTime(mudtTZI, udtUTC, udtLocal)
    
    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::SystemTimeToTzSpecificLocalTime"
    End If
    
    lng = SystemTimeToVariantTime(udtLocal, dtmLocal)

    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::SystemTimeToVariantTime"
    End If

    TimeUTC2Local = dtmLocal
End Function

Public Function TimeLocal2UTC( _
    ByVal dtmLocal_I As Date) _
    As Date
    
    Dim dtmUTC As Date
    Dim udtUTC As SYSTEMTIME
    Dim udtLocal As SYSTEMTIME
    Dim lng As Long
    
    lng = VariantTimeToSystemTime(dtmLocal_I, udtLocal)
    
    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::VariantTimeToSystemTime"
    End If
    
    lng = TzSpecificLocalTimeToSystemTime(mudtTZI, udtLocal, udtUTC)
    
    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::SystemTimeToTzSpecificLocalTime"
    End If
    
    lng = SystemTimeToVariantTime(udtUTC, dtmUTC)

    If lng = 0& Then
        Err.Raise Err.LastDllError Or &H80070000, "::SystemTimeToVariantTime"
    End If

    TimeLocal2UTC = dtmUTC
End Function



E>Весь гугл излазил, немогу найти. Все как сговорились делают одну ошибку, например здесь:

E>http://www.vbusers.com/code/codeget.asp?PostID=1&ThreadID=632
E>берут текущее смещание относительно utc и прибавляют к дате которуе надо переконвертировать
идиоты... :)

E>Т.е. если мы имеем дату 01.01.2010 12:00 то результат будет разным в зависимости от текущего времени. Летом мы ее сконвертируем

E>01.01.2010 14:00, зимой в 01.01.2010 13:00
E>а надо что бы 01.01.2010 12:00 всегда конвертировалась в 01.01.2010 13:00 а
E>01.06.2010 12:00 в 01.06.2010 14:00.
Всегда и везде, вне зависимости от временной зоны? — Ну прибавляй 1 час или 2 часа, дата перевода стрелок везде одна IMHO. :)
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[2]: Excel Vba: Utc time to local
От: Esef Украина  
Дата: 14.10.10 07:59
Оценка:
Здравствуйте, ZAMUNDA, Вы писали:



E>>Весь гугл излазил, немогу найти. Все как сговорились делают одну ошибку, например здесь:

E>>http://www.vbusers.com/code/codeget.asp?PostID=1&ThreadID=632
E>>берут текущее смещание относительно utc и прибавляют к дате которуе надо переконвертировать
ZAM>идиоты...

E>>Т.е. если мы имеем дату 01.01.2010 12:00 то результат будет разным в зависимости от текущего времени. Летом мы ее сконвертируем

E>>01.01.2010 14:00, зимой в 01.01.2010 13:00
E>>а надо что бы 01.01.2010 12:00 всегда конвертировалась в 01.01.2010 13:00 а
E>>01.06.2010 12:00 в 01.06.2010 14:00.
ZAM>Всегда и везде, вне зависимости от временной зоны? — Ну прибавляй 1 час или 2 часа, дата перевода стрелок везде одна IMHO.
Вот на 100% не уверен что везде одна, может в каком нибудь Бангладеше по-другому. Даже не уверен для всех ли временных зон существует летнее/зимнее время. Ну и плюс дата не фиксированная, а это последняя субота марта (летнее) и октября (зимнее) поэтому выходит не очень тривиально.
Лучше такую функцию переложить на ОС. спасибо за пример. Попробую.
Re[3]: Excel Vba: Utc time to local
От: ZAMUNDA Земля для жалоб и предложений
Дата: 16.10.10 00:14
Оценка:
Здравствуйте, Esef, Вы писали:

ZAM>>Всегда и везде, вне зависимости от временной зоны? — Ну прибавляй 1 час или 2 часа, дата перевода стрелок везде одна IMHO. :)

E>Вот на 100% не уверен что везде одна, может в каком нибудь Бангладеше по-другому.
Хм... я думаю, если это международный стандарт, то скорее всего все по одному шаблону действуют. Но опять же не 100% уверен.

E>Даже не уверен для всех ли временных зон существует летнее/зимнее время. Ну и плюс дата не фиксированная, а это последняя субота марта (летнее) и октября (зимнее) поэтому выходит не очень тривиально.

А это не для зон, это для стран. Если мне не изменяет память, в 76 странах принято переводить, всего их 160 или 162. Не помню точно, но помню что около половины.
Да ты сам Wiki почитай. Я, когда этим занимался, всё оттуда подчерпнул.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re: Excel Vba: Utc time to local
От: baranovda Российская Империя  
Дата: 01.11.10 10:53
Оценка:
Здравствуйте, Esef, Вы писали:

E>Киньте кто нибудь правильную функцию для ковертирвания времени в VBA c формата UTC в локальный. Функция должна правильно учитывать смену


В Microsoft CAPICOM есть утилитная функция:

http://msdn.microsoft.com/en-us/library/aa388184(VS.85).aspx
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.