[編輯]我只注意到最後一個針對這一主題也由我自己製作,談論重塑車輪。不過,我認爲下面的類對於上面解釋的方法來說是一個很好的包裝,所以我對它進行了修改以包含我在那裏使用的計算方法。
我不知道VSExpress,但在全VB,我只是GregorianCalendar的擴展功能添加到獲得本週一年和簡化訪問正確的週數:
Public Class IsoWeekCalendar
Inherits Globalization.GregorianCalendar
'Get the ISO week number
Public Overloads Function GetWeekOfYear(d As DateTime) As Integer
Dim Week As Integer
'year is passed byref
GetYearAndWeek(d, Week:=Week)
Return Week
End Function
'Get the year that belongs with the week
Public Function GetWeekYear(d As DateTime) As Integer
Dim Year As Integer
'year is passed byref
GetYearAndWeek(d, Year:=Year)
Return Year
End Function
'Get both the week and year by ref
Public Sub GetYearAndWeek(d As DateTime, Optional ByRef Year As Integer = 0, Optional ByRef Week As Integer = 0)
Dim yearweek = GetYearAndWeek(d)
Year = yearweek.Item1
Week = yearweek.Item2
End Sub
'Get both the week and year
Public Function GetYearAndWeek(d As DateTime) As Tuple(Of Integer, Integer)
Dim year = Me.GetYear(d)
Dim dow = Me.GetDayOfWeek(d)
'Per MSDN, dow is 0 for sunday, per ISO, this should be 7
If (dow = 0) Then dow = 7
'usually, this calculation gives the week number
'http://en.wikipedia.org/wiki/ISO_week_date#Calculation
Dim week As Integer = Math.Floor((Me.GetDayOfYear(d) - dow + 10)/7)
'If the week is 0 or 53, we should do some checks
If (week = 0) Then
'if we get week=0, the week is actually in last year
year -= 1
'A week has 53 weeks only if it starts on a thursday
'or is a leap year starting on a wednesday
Dim jan1st = New Date(year, 1, 1, Me)
If (jan1st.DayOfWeek = DayOfWeek.Thursday _
OrElse jan1st.DayOfWeek = DayOfWeek.Wednesday _
AndAlso Me.IsLeapYear(year)) Then
week = 53
Else
week = 52
End If
ElseIf (week = 53) Then
'determine if this week's thursday is in this year, if
'it's not, this week is also in the next year
Dim thursday = d.AddDays(4 - dow)
If (Me.GetYear(thursday) > year) Then
year += 1
week = 1
End If
End If
Return Tuple.Create(year, week)
End Function
'Get the date from the year, week and DoW, again, using calculation from
'http://en.wikipedia.org/wiki/ISO_week_date#Calculation
Public Function GetDate(year As Integer, week As Integer, Optional day As DayOfWeek = DayOfWeek.Monday) As DateTime
Dim ordinal = (week * 7) + IsoDayOfWeek(day) - (GetIsoDayOfWeek(New Date(year, 1, 4, Me)) + 3)
Return New Date(year, 1, 1, Me).AddDays(ordinal - 1)
End Function
'Get the previous date with the supplied DoW
Public Function GetPrev(d As DateTime, day As DayOfWeek) As DateTime
If (d.DayOfWeek <> day) Then
Return GetPrev(d.AddDays(-1), day)
End If
Return d
End Function
'Get the next date with the supplied DoW
Public Function GetNext(d As DateTime, day As DayOfWeek) As DateTime
If (d.DayOfWeek <> day) Then
Return GetPrev(d.AddDays(1), day)
End If
Return d
End Function
'Get the ISO day of week
Public Function GetIsoDayOfWeek(time As Date) As Integer
Return IsoDayOfWeek(MyBase.GetDayOfWeek(time))
End Function
'Translate .NET DoW to ISO DoW
Public Function IsoDayOfWeek(d As DayOfWeek) As Integer
If (d = DayOfWeek.Sunday) Then Return 7
Return d
End Function
末級
你見過這個:http://stackoverflow.com/questions/1226201/calculate-the-start-and-end-date-of-a-week-given-the-week-number-and-year-in -cs – assylias 2012-03-16 17:01:31
+1感謝@assylias一個非常快速的表情表明它可以提供一些線索。我需要更多時間才能深入瞭解。 – therobyouknow 2012-03-16 17:04:50