除了 DatePart 返回的 2 周数字之外,ISO 周数存在更多问题。
1 月 1 日的星期五应该在上一年的第 53 周
12 月 31 日的星期一应该在下一年的第 1 周
欧洲的许多企业都使用四位数字来同时显示年份和星期。在这些情况下:
Friday #01/01/2021# 应显示为“2153”周
星期一 #12/31/2018# 应显示为“1901”周
我围绕 DatePart 函数创建了 2 个包装器,以添加正确的年份并显示正确的周数,以防 DatePart 出错。
Public Function ISO_YYWW(dat As Date) As String ' ISO 8601 / NEN 2772
Dim ww As Integer
ww = CInt(ISO_WW(dat))
If ww >= 52 And Val(Format(dat, "ww")) <= 2 Then
ISO_YYWW = Format(((Year(dat) - 1) Mod 100), "00") & Format(ww, "00")
ElseIf ww = 1 And Month(dat) = 12 Then
ISO_YYWW = Format(((Year(dat) + 1) Mod 100), "00") & Format(ww, "00")
Else
ISO_YYWW = Format(dat, "YY") & Format(ww, "00")
End If
End Function
Public Function ISO_WW(dat As Date) As String ' ISO 8601 / NEN 2772
If Format(dat, "DD-MM") = "31-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 31-dec on a monday
ISO_WW = "01"
ElseIf Format(dat, "DD-MM") = "30-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 30-dec on a monday
ISO_WW = "01"
ElseIf Format(dat, "DD-MM") = "29-12" And DatePart("W", dat, vbMonday, vbFirstFourDays) = 1 Then ' 29-dec on a monday
ISO_WW = "01"
Else
ISO_WW = Format(DatePart("ww", dat, 2, 2), "00")
End If
End Function
我从 1970 年到 2021 年进行了测试,使用此代码没有发现任何问题
Sub test()
Dim dat As Date, yy As Integer, f As Integer
f = FreeFile
Open CodeDb.Name & ".txt" For Output As #f
Print #f, "date", "day", "ISO_WW / DOW", "ISO_YYWW"
For yy = 1970 To 2021
For dat = CDate("31/12/" & yy) - 7 To CDate("31/12/" & yy) + 7
If ISO_WW(dat) >= 52 Or ISO_WW(dat) = "53" Or Val(ISO_WW(dat)) = 1 Then
Print #f, Format(dat, "yyyy-mm-dd"), Format(dat, "DDD"), ISO_WW(dat) & " / " & DatePart("W", dat, vbMonday, vbFirstFourDays), ISO_YYWW(dat)
End If
Next dat
Print #f, ""
Next yy
Close #f
End Sub