2011年12月17日土曜日

[VB.NET] 週番号から特定の曜日の日付を取得する

指定した年の週番号から、その週の特定の曜日の日付を取得します。
このコードでは第一週をその年の最初の月曜日から、としているため、
例えば2011年の第一週は1月3日からとなります。
2011年1月1,2日は2010年の最終週とみなされます。

''' <summary>
''' 指定した年、週番号の月曜日を取得
''' </summary>
''' <param name="year">年(yyyy)</param>
''' <param name="weekNum">週番号(1-53)</param>
''' <returns></returns>
''' <remarks></remarks>
Shared Function GetFirstDateOfWeek(ByVal year As Integer, ByVal weekNum As Integer) As DateTime
    '第一週をその年最初の月曜日からの週と設定
    Dim weekRule As CalendarWeekRule = CalendarWeekRule.FirstFullWeek
    Dim dtJan1 As DateTime = New DateTime(year, 1, 1)
    '指定した年の最初の月曜日を取得
    'この例では月曜日に固定しているが、DayOfWeek.Mondayを引数として受け取れば
    '任意の曜日の日付を取得できる
    Dim dtFirstMonday As DateTime = GetNearestDayOfWeek(dtJan1, DayOfWeek.Monday)
    Dim cal As Calendar = CultureInfo.CurrentCulture.Calendar
    Dim firstWeek As Integer = cal.GetWeekOfYear(dtJan1, weekRule, DayOfWeek.Monday)
    If firstWeek <= 1 Then
        weekNum -= 1
    End If
    Dim result As DateTime = dtFirstMonday.AddDays(weekNum * 7)
    Return result
End Function

''' <summary>
''' 指定した日付から直近(未来)の指定した曜日の日付を取得
''' </summary>
''' <param name="dtDate">日付</param>
''' <param name="desiredDayOfWeek">曜日</param>
''' <returns></returns>
''' <remarks></remarks>
Shared Function GetNearestDayOfWeek(ByVal dtDate As DateTime, ByVal desiredDayOfWeek As DayOfWeek) As DateTime
    Dim dayOfWeek As DayOfWeek = dtDate.DayOfWeek
    If dayOfWeek = desiredDayOfWeek Then
        Return dtDate
    Else
        Return dtDate.AddDays(((Integer.Parse(System.DayOfWeek.Saturday) - Integer.Parse(dtDate.DayOfWeek) + Integer.Parse(desiredDayOfWeek)) Mod 7) + 1)
    End If
End Function

使用方法はこんな感じです。

Dim year As Integer = 2011
Dim weekNum As Integer = 50
Dim dtMonday As DateTime = GetFirstDateOfWeek(weekYear, weekNum)

※「指定した日付から直近(未来)の指定した曜日の日付を取得する」メソッドに関しては、アジャイルプログラマの日常様のC# で指定した曜日の日を取得をもとに、VBに変換致しました。