取得指定月份第幾週星期幾的日期

來源資料,由Mrkt的程式學習筆記收集。

每個地區甚至每個人對於一年當中的第一週定義都有所不同,
有的人會認為既使1/1出現在週六,那一週就算是該年的第一週。
有的人認為一週都是該年一月的日期時,那一週才算是該年的第一週。
而有的國家、地區會認為1/7才開始算第一週…等等。
於是乎ISO就制定了一些標準:
There are mutually equivalent descriptions of week 01:
  • the week with the year's first Thursday in it (the formal ISO definition),
  • the week with 4 January in it,
  • the first week with the majority (four or more) of its days in the starting year, and
  • the week starting with the Monday in the period 29 December – 4 January.
1.如果該週的星期四也是一月份,則該週就是第一週。
2.如果該週有包含1/4,則該週就是第一週。
3.如果該週一月份的天數超過四天,則該週就是第一週。
4.如果該週的週一為12/29,則該週就是第一週。
而且ISO 8601制定一週開始的第一天為星期一,而非星期日(beginning with Monday and ending with Sunday)。
還有就是weekday number的設定為 1 ~ 7 (對應週一到週日),而非程式常用的0 ~ 6(對
應週日到週六)。

2011-09-29 補充:將運算程式包裝為方法,可以接受跨年度,可以指定要取那一週,可以指定要取星期幾。
public List<DateTime> GetTargetDate(DateTime startDate, DateTime endDate, int weekInterval, DayOfWeek dayOfWeek)
{
    List<DateTime> result = new List<DateTime>();
    
    CultureInfo info = CultureInfo.CurrentCulture;
        
    DateTime firstDate = DateTime.MinValue;
    DateTime firstDateInMonth = DateTime.MinValue;
    DateTime targetDate = DateTime.MinValue;
    
    int startMonth = 0;
    int endMonth = 0;    
 
    int firstWeekNumber = 0;
    int targetWeekNumber = 0;
                    
    for(int x = startDate.Year; x <= endDate.Year; x++)
    {        
        startMonth = (x > startDate.Year) ? 1 : startDate.Month;
        endMonth = (x < endDate.Year) ? 12 : endDate.Month;
        
        for(int i = startMonth; i<= endMonth; i++)
        {
            firstDateInMonth = new DateTime(x, i, 1);
            firstDate = new DateTime(firstDateInMonth.Year, 1, 1);
            
            firstWeekNumber = info.Calendar.GetWeekOfYear(firstDateInMonth, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
            targetWeekNumber = firstWeekNumber + (weekInterval -1);
            
            targetDate = firstDate.AddDays((targetWeekNumber - 1) * 7);
            
            while(targetDate.DayOfWeek != dayOfWeek)
            {
                targetDate = targetDate.AddDays(-1);
            }
            if(targetDate >= startDate)
            {
                result.Add(targetDate);
            }
        }
    }
    
    return result;
}

張貼留言

0 留言