Při určování číslo týdnu datum podle ISO 8601, standardní, vrátí základní funkce volání souboru Oleaut32.dll omylem týden 53 místo 1 týden pro minulé pondělí v některých let.
Norma ISO 8601 se široce používá v Evropě a obsahuje následující:
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."
to lze provést použitím těchto pravidel týdny kalendáře:
Rok je rozdělen do buď 52 a 53 kalendářních týdnů.
Kalendářní týden má 7 dnů. Pondělí je 1, neděle dne 7.
První týden roku kalendáře je obsahující nejméně 4 dnů.
Pokud není za rok uzavření na neděli, buď jeho posledních dnů 1-3 patří do příští rok prvního kalendářního týdne nebo v prvních dnech 1-3 příští rok patří do posledního týdne-aktuální rok.
Pouze rok spuštění nebo uzavírání ve čtvrtek má 53 kalendářních týdnů.
V jazyku Visual Basic a Visual Basic for Applications všechny funkce datum, s výjimkou pro funkci DateSerial pochází z volání souboru Oleaut32.dll. Protože jak Format() a DatePart() funkce může vrátit číslo týdne kalendáře pro dané datum, obě jsou ovlivněny tuto chybu. Chcete-li se vyhnout tomuto problému, je nutné použít alternativní kód, který tento článek poskytuje.
Kroky pro reprodukci chování
Zahájení projektu standardní EXE v jazyce Visual Basic. Ve výchozím nastavení je vytvořena Form1.
Přidejte dvě CommandButtons Form1.
Vložte následující kód do okna kódu 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
Podržte stisknutou klávesu CTRL a stisknutím klávesy G otevřete okno Immediate.
Spuštění projektu, klepněte na Command1 a Poznámka do okna Immediate následující výsledky:
Poznámka, že formátem, všechny týdnů začínat pondělí, tak, aby 12/29/2003 by měly být považovány za zahájení 1 týden a není součástí 53 týden.
Klepněte na Command2 zobrazíte seznam dat v určeném rozsahu, který k tomuto problému dochází. Seznam obsahuje datum, den týden (vždy pondělí) v týdnu vrácené formát (53) a číslo týden se měli vrátit # (1). Například:
Používáte-li funkce Format nebo DatePart, budete muset zkontrolovat vrácená hodnota a 53, je-li spustit další kontrolu a vynutit vrácení 1, v případě potřeby. Tento příklad kódu znázorňuje jedním ze způsobů, jak to provést:
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
je se lze vyhnout použití těchto funkcí k určení, číslo týdne napsáním kódu, který implementuje výše popsaná pravidla ISO 8601. Následující příklad ukazuje funkci náhradní bude vráceno číslo týdne.
Příklad Step by Step
Zahájení projektu standardní EXE v jazyce Visual Basic. Ve výchozím nastavení je vytvořena Form1.
Z nabídky projekt přidat nový modul a vložte následující kód:
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
Přidejte CommandButton Form1.
Vložte následující kód do okna kódu 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
Podržte stisknutou klávesu CTRL a stisknutím klávesy G otevřete okno Immediate.
Spuštění projektu a klepněte na Command1 do okna Immediate následující výsledky:
ID článku: 200299 - Poslední aktualizace: 24. června 2004 - Revize: 3.0
Informace v tomto článku jsou určeny pro produkt:
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
Klíčová slova:
kbmt kbbug kbdatetime kbpending KB200299 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.