【问题标题】:VBA local timezone adjustmentVBA本地时区调整
【发布时间】:2014-02-10 11:29:48
【问题描述】:

假设我有一个当地的太平洋时间 (UTC-8) Excel 值。例如41656.6729717 January 2014 4:09 PM。我无法控制这个值。

我想调整相对于用户本地时间的给定值。例如,都柏林的某个人正在使用 Excel 工作簿。我想调整给定的数字并在他的当地时间显示,18 January 2014 12:09 AM。是否有任何内置的 Excel 功能可以使这一过程顺利进行?

【问题讨论】:

    标签: vba date excel timezone


    【解决方案1】:

    VBA 本身并没有为此提供选项,但是有一个 Windows API 可以让您做您想要做的事情。 This article 描述了如何执行此操作,hereGetTimeZoneInformation 上的 MSDN 页面。

    在 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)
    

    【讨论】:

    • 谢谢,我刚刚提交了一些编辑,包括在函数之前所需的声明,然后是我用来测试的代码行。我用几个时区对此进行了测试,似乎工作正常!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-22
    • 2012-07-06
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多