excel 如何在VBA中确定夏令时?

7jmck4yq  于 2023-04-13  发布在  其他
关注(0)|答案(3)|浏览(114)

什么函数可以让我们知道VBA中的日期是否在DST中?

b1zrtrql

b1zrtrql1#

对于非当前日期(DST 2007+):

首先,你需要一个函数来查找一个月中特定的工作日数:

Public Function NDow(Y As Integer, M As Integer, _
                N As Integer, DOW As Integer) As Date  

' Returns Date of Nth Day of the Week in Month  

NDow = DateSerial(Y, M, (8 - Weekday(DateSerial(Y, M, 1), _
              (DOW + 1) Mod 8)) + ((N - 1) * 7))  

End Function

然后,您可以检查DST日期与以下函数调用:
秋季:NDow(Year(newdate),11,1,1)
Spring:NDow(Year(newdate),3,2,1)

当前日期:

调用Windows API函数GetTimeZoneInformation,它将返回一个带有状态的枚举(整数)。
我从奇普·皮尔森的Excel网站上找到了代码
Pearson's site

qxsslcnc

qxsslcnc2#

如果有人想知道如何计算欧洲的夏令时(中欧时间),我修改了Chip Pearson脚本,三月的最后一个星期日(凌晨2点到凌晨3点)和十月的最后一个星期日(凌晨3点到凌晨2点)是发生小时切换的日子。
下面的代码是Excel中某个按钮的单击事件:

Dim dates As String
dates = "A1:A20"

For Each c In Worksheets("Sheet1").Range(dates).Cells
    If (IsDateWithinDST(c.Value)) Then
        c.Value = DateAdd("h", 1, c.Value)
    End If
Next

包含必要方法的模块可以在here中找到。
More info on DST in Europe.

bttbmeg0

bttbmeg03#

这里是我如何检查DST在美国。当然,有细微差别,如AZ不包括在内。
我在网上看到的许多DST检查只考虑了日期而忽略了时间。因此,他们错误地将1AM和2AM之间报告为DST,而DT已经恢复为ST。
这不仅说明了时间,而且还应说明在更改回标准时间时从凌晨1点到凌晨2点的重复。

' Parameters:
' GMT as a date or timestamp (seconds since 1/1/1970 00:00:00 UTC)
' TZstos as a long (timezone standard time offset in seconds)
' Return array (boolean, gmtOffset)
Public Function IsDST(ByVal GMT As Variant, TZstos As Long) As Variant

    ' Convert a date to timestamp
    If IsDate(GMT) And Not IsNumeric(GMT) Then
        GMT = DateDiff("s", "1/1/1970", GMT)
    End If

    Dim DST_Start_By   As Date,    DST_End_By   As Date
    Dim DST_Start_Date As Date,    DST_End_Date As Date
    Dim DST_Start_TS   As Double,  DST_End_TS   As Double
    Dim TZ_Std_time    As Double,  TZ_DST_time  As Double

    ' Timezone standard and daylight time from GMT
    TZ_Std_time = GMT + TZstos
    TZ_DST_time = GMT + TZstos + 3600

    ' DST Starts at 2:00 AM on second Sunday in March
    DST_Start_By = Year(DateAdd("s", TZ_Std_time, "1/1/1970")) & "-03-14"
    DST_Start_Date = DST_Start_By - (Weekday(DST_Start_By, 1) - 1)
    DST_Start_TS = DateDiff("s", "1/1/1970", DST_Start_Date) + (2 * 3600)

    ' DST Ends at 2:00 AM on first Sunday in November
    DST_End_By = Year(DateAdd("s", TZ_Std_time, "1/1/1970")) & "-11-07"
    DST_End_Date = DST_End_By - (Weekday(DST_End_By, 1) - 1)
    DST_End_TS = DateDiff("s", "1/1/1970", DST_End_Date) + (2 * 3600)

    ' Is it DST and gmtOffset
    If TZ_Std_time >= DST_Start_TS And _
       TZ_DST_time <  DST_End_TS Then
        IsDST = Array(True,  CLng(TZstos + 3600))
    Else
        IsDST = Array(False, CLng(TZstos +    0))
    End If

End Function

像这样打电话给IsDST ...

' GMT offset EST or EDT (standard or daylight time)
TZstatus = IsDST(GMT, (-5 * 3600)) ' GMT and EST offset in seconds
DST = TZstatus(0)
gmtOffset = TZstatus(1)

相关问题