错误: 格式或 DatePart 函数可以返回错误的周数年中的最后一个星期一

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 200299
本文已归档。它按“原样”提供,并且不再更新。
症状
当您使用 格式DatePart 函数使用以下语法的日期确定周编号:
Format(AnyDate, "ww", vbMonday, vbFirstFourDays)DatePart("ww", AnyDate, vbMonday, vbFirstFourDays)				
周 53 时它应该是第 1 周的形式返回某些日历年中上月。
原因
在确定了 ISO 8601 标准对应的日期的星期数时 Oleaut32.dll 文件基础的函数调用错误地返回特定年中周 53 而不是第 1 周的最后一个星期一。
解决方案
使用用户定义函数返回的 ISO 8601 标准规则基于的周数。在这篇文章中包含一个示例。
状态
Microsoft 已经确认这是 Oleaut32.dll 文件中的问题。
更多信息
ISO 8601 标准在欧洲广泛,包括以下:
  ISO 8601 "Data elements and interchange formats - Information interchange   - Representation of dates and times"  ISO 8601 : 1988 (E) paragraph 3.17:  "week, calendar: A seven day period within a calendar year, starting  on a Monday and identified by its ordinal number within the year;  the first calendar week of the year is the one that includes the  first Thursday of that year. In the Gregorian calendar, this is  equivalent to the week which includes 4 January."				
这可以通过日历周应用这些规则来实现:
  • 一年分为 53 或 52 日历周。
  • 日历周有 7 天。星期一是第一天,星期日是 7 天。
  • 一年的第一个日历周是包含在至少 4 个工作日。
  • 如果一年不一个星期日结束,其 1-3 天属于下一年的第一个日历周,或下一年中的第一个 1-3 天属于存在年的最后一个日历周。
  • 仅一年开始或结束是星期四有 53 日历周。
在 Visual Basic 和 Visual Basic 应用程序的除外 DateSerial 功能的所有日期功能都来自 Oleaut32.dll 文件的调用。因为 format ()DatePart() 函数可以返回给定日期的日历周编号,同时会影响此 bug。若要不必此问题,您必须使用这篇文章介绍了在其他代码。

重现行为的步骤

  1. 启动 Visual Basic 中的标准 EXE 项目。默认情况下创建 Form1。
  2. 向 Form1 中添加两个 CommandButtons
  3. 将以下代码粘贴到 Form1 的代码窗口中:
    Option ExplicitPrivate Sub Command1_Click()' This code tests a "problem" date and the days around itDim DateValue As DateDim i As IntegerDebug.Print "   Format function:"DateValue = #12/27/2003#For i = 1 To 4   ' examine the last 4 days of the year    DateValue = DateAdd("d", 1, DateValue)    Debug.Print "Date: " & DateValue & "   Day: " & _      Format(DateValue, "ddd") & "   Week: " & _      Format(DateValue, "ww", vbMonday, vbFirstFourDays)Next iEnd SubPrivate Sub Command2_Click()' This code lists all "Problem" dates within a specified range  Dim MyDate As Date  Dim Years As Long  Dim days As Long  Dim woy1 As Long  Dim woy2 As Long  Dim ToPrint As String  For Years = 1850 To 2050    For days = 0 To 3      MyDate = DateSerial(Years, 12, 28 + days)      woy1 = Format(MyDate, "ww", vbMonday, vbFirstFourDays)      woy2 = Format(MyDate, "ww", vbMonday, vbFirstFourDays)      If woy2 > 52 Then        If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then _          woy2 = 1      End If      If woy1 <> woy2 Then        ToPrint = MyDate & String(13 - Len(CStr(MyDate)), " ")        ToPrint = ToPrint & Format(MyDate, "dddd") & _          String(10 - Len(Format(MyDate, "dddd")), " ")        ToPrint = ToPrint & woy1 & String(5 - Len(CStr(woy1)), " ")        ToPrint = ToPrint & woy2        Debug.Print ToPrint      End If    Next days  Next YearsEnd Sub					
  4. 按住 CTRL 键,然后按要打开立即窗口 G 键。
  5. 运行该项目,单击上 Command1,并注意在立即窗口中的下列结果:
       Format function:Date: 12/28/03   Day: Sun   Week: 52Date: 12/29/03   Day: Mon   Week: 53Date: 12/30/03   Day: Tue   Week: 1Date: 12/31/03   Day: Wed   Week: 1						
    注意这种格式与所有的周开始与星期一,以便开始的第 1 周和不是周 53 的一部分,应考虑 12/29/2003年。
  6. 单击上 Command2 若要查看的指定区域中遇到此问题的日期列表。该列表包含日期、 周的天 (始终星期一) Week # 所返回的格式 (53) 和它应该返回的周数 (1)。例如:
    12/29/1851   Monday    53   112/31/1855   Monday    53   112/30/1867   Monday    53   112/29/1879   Monday    53   112/31/1883   Monday    53   112/30/1895   Monday    53   1...					

解决方法

如果您使用 格式DatePart 函数,则需要检查返回值和时它是 53,, 运行另一个检查和强制为 1,返回,如有必要。此代码示例演示如何执行此操作的一种方法:
Function WOY (MyDate As Date) As Integer   ' Week Of Year  WOY = Format(MyDate, "ww", vbMonday, vbFirstFourDays)  If WOY > 52 Then    If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then WOY = 1  End IfEnd Function				
您可以避免使用这些函数确定通过编写代码来实现上述的 ISO 8601 规则的周数。下面的示例演示如何替换函数可返回周数。

步骤示例

  1. 启动 Visual Basic 中的标准 EXE 项目。默认情况下创建 Form1。
  2. 项目 菜单中添加一个新的模块,然后粘贴下面的代码:
    Option ExplicitFunction WeekNumber(InDate As Date) As Integer  Dim DayNo As Integer  Dim StartDays As Integer  Dim StopDays As Integer  Dim StartDay As Integer  Dim StopDay As Integer  Dim VNumber As Integer  Dim ThurFlag As Boolean  DayNo = Days(InDate)  StartDay = Weekday(DateSerial(Year(InDate), 1, 1)) - 1  StopDay = Weekday(DateSerial(Year(InDate), 12, 31)) - 1  ' Number of days belonging to first calendar week  StartDays = 7 - (StartDay - 1)  ' Number of days belonging to last calendar week  StopDays = 7 - (StopDay - 1)  ' Test to see if the year will have 53 weeks or not  If StartDay = 4 Or StopDay = 4 Then ThurFlag = True Else ThurFlag = False  VNumber = (DayNo - StartDays - 4) / 7  ' If first week has 4 or more days, it will be calendar week 1  ' If first week has less than 4 days, it will belong to last year's  ' last calendar week  If StartDays >= 4 Then      WeekNumber = Fix(VNumber) + 2   Else      WeekNumber = Fix(VNumber) + 1  End If  ' Handle years whose last days will belong to coming year's first   ' calendar week  If WeekNumber > 52 And ThurFlag = False Then WeekNumber = 1  ' Handle years whose first days will belong to the last year's   ' last calendar week  If WeekNumber = 0 Then     WeekNumber = WeekNumber(DateSerial(Year(InDate) - 1, 12, 31))  End IfEnd FunctionFunction Days(DayNo As Date) As Integer  Days = DayNo - DateSerial(Year(DayNo), 1, 0)End Function					
  3. 向 Form1 中添加一个 命令按钮
  4. 将以下代码粘贴到 Form1 的代码窗口中:
    Private Sub Command1_Click()   Dim DateValue As Date, i As Integer      Debug.Print "   WeekNumber function:"   DateValue = #12/27/2003#   For i = 1 To 4   ' examine the last 4 days of the year       DateValue = DateAdd("d", 1, DateValue)       Debug.Print "Date: " & DateValue & "   Day: " & _          Format(DateValue, "ddd") & "   Week: " & WeekNumber(DateValue)   Next iEnd Sub					
  5. 按住 CTRL 键,然后按要打开立即窗口 G 键。
  6. 运行该项目,然后单击上 Command1 若要查看在立即窗口中的下列结果:
       WeekNumber function:Date: 12/28/03   Day: Sun   Week: 52Date: 12/29/03   Day: Mon   Week: 1Date: 12/30/03   Day: Tue   Week: 1Date: 12/31/03   Day: Wed   Week: 1					
    笔记的星期一被视为它应该是作为第 1 周。

属性

文章 ID:200299 - 上次审阅时间:12/05/2015 10:27:27 - 修订版本: 3.0

Microsoft Visual Basic 6.0 学习版, Microsoft Visual Basic 6.0 专业版, Microsoft Visual Basic Enterprise Edition for Windows 6.0, Microsoft Visual Basic Control Creation Edition, Microsoft Visual Basic 5.0 学习版, Microsoft Visual Basic 5.0 专业版, Microsoft Visual Basic 5.0 企业版, Microsoft Visual Basic 4.0 标准版, Microsoft Visual Basic 4.0 专业版, Microsoft Visual Basic 4.0 32-Bit Enterprise Edition, Microsoft Visual Basic for Applications 5.0, Microsoft Visual Basic for Applications 6.0

  • kbnosurvey kbarchive kbmt kbbug kbdatetime kbpending KB200299 KbMtzh
反馈