Format veya DatePart işlevleri, Yılın son Pazartesi günü için yanlış hafta numarası döndürebilir
Uyarı
Bu işlevin kullanımıyla ilgili bir sorun var. Bazı takvim yıllarındaki son Pazartesi, 1. hafta olması gerektiğinde 53. hafta olarak döndürülebilir. Daha fazla bilgi ve geçici çözüm için bkz. Format veya DatePart işlevleri yılın son Pazartesi günü için yanlış hafta numarası döndürebilir.
Belirtiler
Aşağıdaki söz dizimini kullanarak tarihlerin hafta numarasını belirlemek için Format veya DatePart işlevini kullandığınızda:
Format(AnyDate, "ww", vbMonday, vbFirstFourDays)
DatePart("ww", AnyDate, vbMonday, vbFirstFourDays)
bazı takvim yıllarındaki son Pazartesi, 1. hafta olması gerektiğinde 53. hafta olarak döndürülür.
Neden
Iso 8601 standardına göre bir tarihin hafta numarasını belirlerken, Oleaut32.dll dosyasına yapılan temel işlev çağrısı, belirli yıllarda geçen Pazartesi için yanlışlıkla 1. hafta yerine 53. haftayı döndürür.
Çözüm
ISO 8601 standardının kurallarına göre Hafta numarasını döndürmek için kullanıcı tanımlı bir işlev kullanın. Bu makalede bir örnek verilmiştir.
Ek Bilgi
ISO 8601 standardı Avrupa'da yaygın olarak kullanılır ve aşağıdakileri içerir:
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."
Bu, Takvim haftaları için bu kurallar uygulanarak uygulanabilir:
- Bir yıl 52 veya 53 takvim haftasına ayrılır.
- Takvim haftası 7 gündür. Pazartesi 1. gün, Pazar ise 7.
- Yılın ilk takvim haftası en az 4 gün içeren haftadır.
- Bir yıl Pazar günü sona ermezse, 1-3 son günü sonraki yılın ilk takvim haftasına veya gelecek yılın ilk 1-3 günü, mevcut yılın son takvim haftasına aittir.
- Perşembe günü başlayan veya sona eden bir yılın 53 takvim haftası vardır.
Visual Basic ve Visual Basic for Applications'da DateSerial işlevi dışındaki tüm tarih işlevleri Oleaut32.dll dosyasına yapılan çağrılardan gelir. Format() ve DatePart() işlevlerinin her ikisi de belirli bir tarih için takvim haftası numarasını döndürebileceğinden, her ikisi de bu hatadan etkilenir. Bu sorunu önlemek için, bu makalede sunulan alternatif kodu kullanmanız gerekir.
Davranışı Yeniden Oluşturma Adımları
Visual Basic projesini bir Office uygulamasında açın (Alt + F11).
Proje menüsünden yeni bir modül ekleyin.
Aşağıdaki kodu modüle yapıştırın:
Option Explicit Public Function Test1() ' 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 Function Public Function Test2() ' 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 Function
Henüz açık değilse Anında Pencere'yi açmak için (Ctrl + G) kullanın.
Tür ? Anında penceresinde test1 yapın ve Enter tuşuna basın, Anında penceresinde aşağıdaki sonuçları not edin:
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
Bu biçimle, tüm haftalar Pazartesi ile başlar, böylece 29/12/2003, 53. Haftanın parçası değil, 1. Haftanın başlangıcı olarak kabul edilmelidir.
Tür ? Bu sorunla karşılaşan belirtilen aralıktaki tarihlerin listesini görmek için Anlık penceresinde Test2'ye basın ve Enter tuşuna basın. Listede tarih, Hafta günü (her zaman Pazartesi), Biçim tarafından döndürülen Hafta # (53) ve döndürülmesi gereken Hafta numarası (1) yer alır. Örneğin:
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 ...
Geçi -ci çözüm
Format veya DatePart işlevlerini kullanıyorsanız, dönüş değerini denetlemeniz gerekir. 53 olduğunda, başka bir denetim çalıştırın ve gerekirse 1'in geri dönüşünü zorlayın. Bu kod örneği bunu yapmak için bir yol gösterir:
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
Yukarıda açıklanan ISO 8601 kurallarını uygulayan kod yazarak Hafta numarasını belirlemek için bu işlevleri kullanmaktan kaçınabilirsiniz. Aşağıdaki örnekte, Hafta numarasını döndürmek için bir değiştirme işlevi gösterilmektedir.
Adım Adım Örnek
Visual Basic projesini bir Office uygulamasında açın (Alt + F11).
Proje menüsünden yeni bir modül ekleyin.
Aşağıdaki kodu modüle yapıştırın:
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 Public Function Test3() 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 Function
Henüz açık değilse Anında Pencere'yi açmak için (Ctrl + G) kullanın.
Tür ? Anlık penceresinde test3 ve Enter tuşuna basın, Anında penceresinde aşağıdaki sonuçları not edin:
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
Pazartesi'nin olması gerektiği gibi 1. Hafta olarak kabul edildiğini unutmayın.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin