Киньте кто нибудь правильную функцию для ковертирвания времени в 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.
Здравствуйте, 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) Козьма Прутков
Здравствуйте, 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% не уверен что везде одна, может в каком нибудь Бангладеше по-другому. Даже не уверен для всех ли временных зон существует летнее/зимнее время. Ну и плюс дата не фиксированная, а это последняя субота марта (летнее) и октября (зимнее) поэтому выходит не очень тривиально.
Лучше такую функцию переложить на ОС. спасибо за пример. Попробую.
Здравствуйте, Esef, Вы писали:
ZAM>>Всегда и везде, вне зависимости от временной зоны? — Ну прибавляй 1 час или 2 часа, дата перевода стрелок везде одна IMHO. :)
E>Вот на 100% не уверен что везде одна, может в каком нибудь Бангладеше по-другому.
Хм... я думаю, если это международный стандарт, то скорее всего все по одному шаблону действуют. Но опять же не 100% уверен.
E>Даже не уверен для всех ли временных зон существует летнее/зимнее время. Ну и плюс дата не фиксированная, а это последняя субота марта (летнее) и октября (зимнее) поэтому выходит не очень тривиально.
А это не для зон, это для стран. Если мне не изменяет память, в 76 странах принято переводить, всего их 160 или 162. Не помню точно, но помню что около половины.
Да ты сам
Wiki почитай. Я, когда этим занимался, всё оттуда подчерпнул.
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Здравствуйте, Esef, Вы писали:
E>Киньте кто нибудь правильную функцию для ковертирвания времени в VBA c формата UTC в локальный. Функция должна правильно учитывать смену
В Microsoft CAPICOM есть утилитная функция:
http://msdn.microsoft.com/en-us/library/aa388184(VS.85).aspx