注意: 格式或日期部份函數可以傳回錯誤的週數的最後一個星期一年份中

文章翻譯 文章翻譯
文章編號: 200299 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

徵狀

當您使用 [格式] 或 [日期部份 的函式來判斷週數的日期使用下列語法:
Format(AnyDate, "ww", vbMonday, vbFirstFourDays)

DatePart("ww", AnyDate, vbMonday, vbFirstFourDays)
				
一些行事曆年最後一星期一會當成的週 53 當它應該是第 1 週。

發生的原因

在決定日期,以根據以標準的 ISO 8601 的週數時一定檔案基礎的函式呼叫會誤把傳回而不是中的第 1 週的最後一個星期一的週 53 在特定的年份。

解決方案

使用使用者定義函式傳回根據 ISO 8601 標準的規則的週數。本文包含範例。

狀況說明

Microsoft 已確認這是一定檔案中的問題。

其他相關資訊

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."
				
這可以藉由套用這些規則的行事曆週實作:
  • 一年分成 52 或是 53 行事曆週。
  • 月曆週有 7 天。星期一是第一天,星期天是 7 天。
  • 一年中的第一個的行事曆週就是包含至少 4 天。
  • 如果一年不認為上週日,可能是其 1-3 的最後一天隸屬於下年度第一個月曆週,或下一年中的第一個的 1-3 天屬於存在年最後一個行事曆週。
  • 只有一年開始,或在一個星期四多久有 53 行事曆週。
在 Visual Basic 和應用程式的 Visual Basic,以外的 DateSerial] 函數的所有日期功能都來自一定檔案的呼叫。因為 Format ()DatePart() 函數可以傳回給定日期的行事曆週數,兩者會受到這個 Bug。若要避免這個問題,您必須使用替代本文提供的程式碼。

重製行為的步驟

  1. 在 Visual Basic 中啟動標準執行檔的專案。預設會建立 Form1。
  2. 將兩個 CommandButtons 加入至 Form1。
  3. 下列程式碼貼入 Form1 的程式碼視窗:
    Option Explicit
    
    Private Sub Command1_Click()
    ' This code tests a "problem" date and the days around it
    Dim DateValue As Date
    Dim i As Integer
    
    Debug.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 i
    End Sub
    
    Private 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 Years
    End Sub
    					
  4. 按住 CTRL 鍵並按 G 鍵,以開啟 [即時運算] 視窗。
  5. 執行專案,並按一下 [Command1,請注意 [即時運算] 視窗中的下列結果:
       Format function:
    Date: 12/28/03   Day: Sun   Week: 52
    Date: 12/29/03   Day: Mon   Week: 53
    Date: 12/30/03   Day: Tue   Week: 1
    Date: 12/31/03   Day: Wed   Week: 1
    						
    請注意此格式的所有週都開頭星期一,這樣 12 / 29 / 2003年應該被視為週 1 和不屬於週 53 的都開始。
  6. 按一下 [上 Command2 若要查看清單中指定的範圍遇到這個問題的日期。此清單包括 [日期、 週日 (永遠星期一) [週 # 傳回的格式 (53) 以及它應該傳回的週數 (1)。例如:
    12/29/1851   Monday    53   1
    12/31/1855   Monday    53   1
    12/30/1867   Monday    53   1
    12/29/1879   Monday    53   1
    12/31/1883   Monday    53   1
    12/30/1895   Monday    53   1
    ...
    					

因應措施

如果您使用 [格式] 或 [日期部份 的功能時,您要檢查傳回值及時 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 If
End Function
				
您可以避免使用這些函式來撰寫程式碼會實作上面所述的 ISO 8601 規則判斷週數。下列範例會示範取代函式,以傳回一週數。

逐步解說範例

  1. 在 Visual Basic 中啟動標準執行檔的專案。預設會建立 Form1。
  2. 從 [專案] 功能表將加入新模組並再貼上下列程式碼中:
    Option Explicit
    
    Function 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 If
    End Function
    
    Function 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 i
    End Sub
    					
  5. 按住 CTRL 鍵並按 G 鍵,以開啟 [即時運算] 視窗。
  6. 執行專案,按一下 [上 Command1 若要查看的 [即時運算] 視窗中下列結果:
       WeekNumber function:
    Date: 12/28/03   Day: Sun   Week: 52
    Date: 12/29/03   Day: Mon   Week: 1
    Date: 12/30/03   Day: Tue   Week: 1
    Date: 12/31/03   Day: Wed   Week: 1
    					
    筆記該星期一被視為是週 1 當它應該是。

屬性

文章編號: 200299 - 上次校閱: 2004年6月24日 - 版次: 3.0
這篇文章中的資訊適用於:
  • Microsoft Visual Basic 6.0 Learning Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic Enterprise Edition for Windows 6.0
  • Microsoft Visual Basic Control Creation Edition
  • Microsoft Visual Basic 5.0 Learning Edition
  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic 4.0 32-Bit Enterprise Edition
  • Microsoft Visual Basic for Applications 5.0
  • Microsoft Visual Basic for Applications 6.0
關鍵字:?
kbmt kbbug kbdatetime kbpending KB200299 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:200299
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com