Извлечь текущее количество часов смещения локального компьютера от времени UTC (с VBA) - PullRequest
0 голосов
/ 09 июня 2018

Люди используют мои проекты в нескольких часовых поясах.

Какой самый быстрый способ получить только текущее количество часов , на котором локальная машина смещена от UTC с использованием VBA, с цельюконвертировать метки времени?

1 Ответ

0 голосов
/ 09 июня 2018

Вот два готовых к использованию способа получить текущее количество часов, смещенное относительно времени UTC, не более и не менее:

Метод первый: использование «любого» API

Option Explicit

Function hoursOffsetFromUTC() As Single
    'returns current #hours difference between UTC & Local System Time
    'On Error GoTo uError
    Dim xmlHTTP As Object, strUTC As String, dtUTC As Date
    Set xmlHTTP = CreateObject("MSXML2.XMLHTTP")
    xmlHTTP.Open "GET", "https://maps.googleapis.com/maps/api/" & _
        "timezone/json?location=" & Int(Rnd() * 99) & ",0&timestamp=" & Int(Rnd() * 99), False
    xmlHTTP.send 'send randomized reqeust to avoid cached results
    strUTC = Mid(xmlHTTP.getResponseHeader("date"), 6, 20)
    Set xmlHTTP = Nothing
    dtUTC = DateValue(strUTC) + TimeValue(strUTC)
    hoursOffsetFromUTC = Round((Now() - dtUTC) * 48, 0) / 2 'nearest 0.5
    Exit Function
uError:
    MsgBox "Couldn't get UTC time." & vbLf & vbLf & _
        "Err#" & Err & ": " & Err.Description, vbExclamation, "Error!"
End Function
  • Пример использования: MsgBox hoursOffsetFromUTC

Метод второй: использование Windows API

Private 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

Private Type TIME_ZONE_INFORMATION
    Bias As LongPtr
    StandardName(0 To 31) As Integer
    StandardDate As SYSTEMTIME
    StandardBias As LongPtr
    DaylightName(0 To 31) As Integer
    DaylightDate As SYSTEMTIME
    DaylightBias As LongPtr
End Type

Private Declare PtrSafe Function GetTimeZoneInformation Lib "kernel32" _
    (lpTimeZoneInformation As TIME_ZONE_INFORMATION) As Long

Function hoursOffsetFromUTC_Win() As Single
    Dim TZI As TIME_ZONE_INFORMATION
    If GetTimeZoneInformation(TZI) = 2 Then
        hoursOffsetFromUTC_Win = 0 - ((TZI.Bias + TZI.DaylightBias) / 60)
    Else
        hoursOffsetFromUTC_Win = 0 - (TZI.Bias / 60)
    End If
End Function
  • Пример использования: MsgBox hoursOffsetFromUTC_Win

Метод первый меньше кода, но требует подключения к интернету.Он вызывает Google API со случайным числом, чтобы избежать кеширования, и игнорирует тело ответа, захватывает дату запроса, возвращенную в заголовке ответа, и сравнивает ее с местным системным временем.(Можно использовать любой API, который возвращает текущие UTC / GMT в заголовке.)

Метод два требует объявления двух типов и внешней функции, но работает без подключения к Интернету, используя функциональностьиз внутреннего kernel32 API Windows.


Преобразование меток времени:

  • Чтобы преобразовать числовую метку времени Unix / Epoch в " Excel Time ":

    (Отметка времени / 86400) + 25569 = ExcelTime

  • или, наоборот, из отметки времени Excel в эпоху:

    (ExcelTime - 25569) * 86400 = Отметка времени

(Они не включают в себя настройку часового пояса, поэтому вы можете добавлять / вычитать его по мере необходимости.)


Дополнительная информация:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...