VBA 将日期转换为周数

Posted

技术标签:

【中文标题】VBA 将日期转换为周数【英文标题】:VBA Convert date to week number 【发布时间】:2018-04-08 23:54:00 【问题描述】:

在 VBA 中,我想将 03/11/2017(DD/MM/YYYY) 的日期转换为该日期的周数。

到目前为止,我有以下代码:

   'geting the date out of the string
    HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
   'switch "." to "/"
    HeadlineTemp = Replace(HeadlineTemp, ".", "/")
   'convert to a date
    FristVRFirstKW = CDate(HeadlineTemp)

现在,我需要一个函数将该日期转换为一年中的周数。第一个工作日是星期一。

【问题讨论】:

Excel 有一个内置公式 (WEEKNUM)。 @ImaginaryHuman 是的,我知道在 Excel 中是内置公式,但显然,在 VBA 中不是......所以我需要创建一个。 试试这个:MsgBox "We are currently in week " & Application.WorksheetFunction.WeekNum(DateSerial(2017, 10, 27)) 【参考方案1】:

要将星期一作为第一天的周数,请使用以下命令:

WorksheetFunction.WeekNum(now, vbMonday)

【讨论】:

感谢 Vityata,也感谢您帮助我编辑。【参考方案2】:

使用 VBA,要将日期转换为 isoWeeknumber,您只需要 DatePart 函数(其中 DT 是感兴趣的日期):

isoWeekNumber = DatePart("ww", DT, vbMonday, vbFirstFourDays)

如果您想使用 ISO 8601 中未指定的其他定义,请研究 FirstDayOfWeekFirstWeekOfYear 的其他一些选项

注意

正如@Mike85 所指出的,DatePart(以及Format)函数中存在一个错误,其中星期一可能被错误地赋予了周数 53,而它应该是 1。

有多种解决方法。

在 Excel 2013+(Excel for Mac 2011+)中,您可以使用 ISO 周数:

isoWeekNumber = WorksheetFunction.isoWeekNum(dt)

对于较早的版本,您可以测试星期一并根据需要进行调整,也可以编写单独的例程。

【讨论】:

感谢您的提示。我肯定会尝试这样做。 这个函数有闰年的bug。需要四处走走。看我的回答。 @mike85 感谢您指出这一点。当我写这个答案时,我不知道2017 中的那个错误。【参考方案3】:

当涉及到周数时要小心,因为周围有不同的定义。 Excel 定义不同于 ISO 定义。获取 ISO 周数使用(复制自 http://www.rondebruin.nl/win/s8/win001.htm)

Public Function IsoWeekNumber(d As Date) As Integer
    Dim d2 As Long
    d2 = DateSerial(Year(d - Weekday(d - 1) + 4), 1, 3)
    IsoWeekNumber = Int((d - d2 + Weekday(d2) + 5) / 7)
End Function

【讨论】:

感谢@FunThomas,提供帮助。【参考方案4】:

WeekdayName( number, [abbreviate], [firstdayofweek] ) WeekdayName(2) 结果:“星期一”

WeekdayName(2, TRUE) 结果:“星期一”

WeekdayName(2, TRUE, vbMonday) 结果:“星期一”

【讨论】:

很好的信息,但实际上并没有解决要求从日期开始的周数的问题(实际上由拉尔夫的评论回答)【参考方案5】:

所以,这是我最后的完美版本

Public Function IsoWeekNumber(d As Date) As String

    Dim kwtemp As String

    kwtemp = DatePart("ww", d, vbMonday, vbFirstFourDays)

    If Len(kwtemp) = 1 Then kwtemp = "0" & kwtemp

    IsoWeekNumber = kwtemp

End Function

If Application.International(xlMDY) = True Then

HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
HeadlineTemp = Replace(HeadlineTemp, ".", "/")
HeadlineTemp = Mid(HeadlineTemp, 4, 3) & Left(HeadlineTemp, 2) & Right(HeadlineTemp, 5)
VRFirstKW = CDate(HeadlineTemp)
HeadlineTempEndKW = Mid(VRHeadline, InStr(VRHeadline, "]") - 10, 10)
HeadlineTempEndKW = Replace(HeadlineTempEndKW, ".", "/")
HeadlineTempEndKW = Mid(HeadlineTempEndKW, 4, 3) & Left(HeadlineTempEndKW, 2) & Right(HeadlineTempEndKW, 5)
VREndKW = CDate(HeadlineTempEndKW)
VRKW = "KW" & IsoWeekNumber(VRFirstKW) & "-" & IsoWeekNumber(VREndKW) & "/" & Year(VREndKW)

    Else 'don't switch position of the month with days

    HeadlineTemp = Mid(VRHeadline, InStr(VRHeadline, "[") + 1, 10)
    HeadlineTemp = Replace(HeadlineTemp, ".", "/")
    VRFirstKW = CDate(HeadlineTemp)
    HeadlineTempEndKW = Mid(VRHeadline, InStr(VRHeadline, "]") - 10, 10)
    HeadlineTempEndKW = Replace(HeadlineTempEndKW, ".", "/")
    VREndKW = CDate(HeadlineTempEndKW)
    VRKW = "KW" & IsoWeekNumber(VRFirstKW) & "-" & IsoWeekNumber(VREndKW) & "/" & Year(VREndKW)

【讨论】:

【参考方案6】:

使用带有错误解决方法的 datepart 计算 ISO 年份:

'Test 2007-12-31 should return W01Y2008

myDate = "2007-12-31"

ISOWeek = DatePart("ww", myDate, vbMonday, vbFirstFourDays)
Week1 = DatePart("ww", myDate, vbMonday, vbFirstFourDays)
Week2 = DatePart("ww", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays)
ISOYear = DatePart("yyyy", myDate, vbMonday, vbFirstFourDays)
Year1 = DatePart("yyyy", myDate, vbMonday, vbFirstFourDays)
Year2 = DatePart("yyyy", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays)

If ISOWeek = 53 And DatePart("ww", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays) = 2 Then
   ISOWeek = 1
End If

if ISOWeek = 1 And DatePart("yyyy", DateAdd("d", 7, myDate), vbMonday, vbFirstFourDays) > ISOYear Then
 ISOYear = ISOYear + 1
End If

MsgBox("W" & ISOWeek & "Y" & ISOYear)

' Result in W01Y2008

【讨论】:

【参考方案7】:

Cw = DatePart("ww", d, vbWednesday, vbFirstFullWeek)

ww -> 日历周

d -> 日期变量

vbWednesday -> 一周的开始日期

vbFirstFullWeek -> 年份将从第一个 7 开始

【讨论】:

以上是关于VBA 将日期转换为周数的主要内容,如果未能解决你的问题,请参考以下文章

怎么取两个日期之间的周数

字符串日期转换为周

转换日期:从年份和周数转换为日期时间

JS将日期转换成当年的周数(work week)

python - 如何将带有年份的周数转换为python pandas中的日期时间格式?

PLSQL中SQL语句怎样转换日期型函数为字符型?