2014-01-21 10 views
3

Скажем, у меня есть местное тихоокеанское время (UTC-8) значение Excel. Например, 41656.67297 - 17 January 2014 4:09 PM. Я не контролирую эту ценность.Настройка локального часового пояса VBA

Я хочу настроить данное значение относительно местного времени пользователя. Скажем, например, кто-то из Дублина использует книгу Excel. Я хочу настроить данный номер и отобразить его в свое местное время, 18 January 2014 12:09 AM. Есть ли встроенные функции Excel, чтобы сделать это гладким?

ответ

4

VBA не предоставляет возможности для этого изначально, но есть Windows API, который позволит вам делать то, что вы ищете. This article описывает, как это сделать, и here - это страница MSDN на GetTimeZoneInformation.

На странице CPearson, делают эти заявления первых:

Option Explicit 

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 


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
' NOTE: If you are using the Windows WinAPI Viewer Add-In to get 
' function declarations, not that there is an error in the 
' TIME_ZONE_INFORMATION structure. It defines StandardName and 
' DaylightName As 32. This is fine if you have an Option Base 
' directive to set the lower bound of arrays to 1. However, if 
' your Option Base directive is set to 0 or you have no 
' Option Base diretive, the code won't work. Instead, 
' change the (32) to (0 To 31). 
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 

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


'''''''''''''''''''''''''''''''''''''''''''''' 
' These give symbolic names to the time zone 
' values returned by GetTimeZoneInformation . 
'''''''''''''''''''''''''''''''''''''''''''''' 

Private Enum TIME_ZONE 
    TIME_ZONE_ID_INVALID = 0  ' Cannot determine DST 
    TIME_ZONE_STANDARD = 1   ' Standard Time, not Daylight 
    TIME_ZONE_DAYLIGHT = 2   ' Daylight Time, not Standard 
End Enum 


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

Private Declare Sub GetSystemTime Lib "kernel32" _ 
    (lpSystemTime As SYSTEMTIME) 

Тогда эта функция будет найти местное время пользователя и смещение от GMT:

Function LocalOffsetFromGMT(Optional AsHours As Boolean = False, _ 
    Optional AdjustForDST As Boolean = False) As Double 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 
' LocalOffsetFromGMT 
' This returns the amount of time in minutes (if AsHours is omitted or 
' false) or hours (if AsHours is True) that should be *added* to the 
' local time to get GMT. If AdjustForDST is missing or false, 
' the unmodified difference is returned. (e.g., Kansas City to London 
' is 6 hours normally, 5 hours during DST. If AdjustForDST is False, 
' the resultif 6 hours. If AdjustForDST is True, the result is 5 hours 
' if DST is in effect.) 
' Note that the return type of the function is a Double not a Long. This 
' is to accomodate those few places in the world where the GMT offset 
' is not an even hour, such as Newfoundland, Canada, where the offset is 
' on a half-hour displacement. 
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 

Dim TBias As Long 
Dim TZI As TIME_ZONE_INFORMATION 
Dim DST As TIME_ZONE 
DST = GetTimeZoneInformation(TZI) 

If DST = TIME_ZONE_DAYLIGHT Then 
    If AdjustForDST = True Then 
     TBias = TZI.Bias + TZI.DaylightBias 
    Else 
     TBias = TZI.Bias 
    End If 
Else 
    TBias = TZI.Bias 
End If 
If AsHours = True Then 
    TBias = TBias/60 
End If 

LocalOffsetFromGMT = TBias 

End Function 

Вы можете проверить код:

MsgBox (LocalOffsetFromGMT()) 

Затем, чтобы добавить это смещение в исходное время, вы можете сделать следующее:

OriginalTime + TIME(LocalOffsetFromGMT(True, True), 0, 0) 
+0

Спасибо, я просто представил некоторые изменения, чтобы включить необходимые декларации, необходимые перед функцией, а затем строку кода, которую я использовал для тестирования. Я проверил это с несколькими часовыми поясами и, похоже, отлично работает! –

Смежные вопросы