Расчет номера недели для определенной даты

Функция вернет вам количество недель прошедших с начала года по день и месяц которые вы укажите при обращении к ней.

Смотрите код ниже:
public static int GetWeekNumber(DateTime dtPassed)
{
    CultureInfo ciCurr = CultureInfo.CurrentCulture;
    int weekNum = ciCurr.Calendar.GetWeekOfYear(dtPassed, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    return weekNum;
}
Например, для первого сентября 2012 года код вернет вам цифру 35, означающую что в этот день, была 35 неделя года:
private void button1_Click(object sender, EventArgs e)
{
    DateTime date = new DateTime(2012,9,1);

    MessageBox.Show(GetWeekNumber(date).ToString());
}

Для работы нам понадобится подключить пространство имен:

using System.Globalization;
      Благодаря внимательности наших читателей, была выявлена некоторая особенность данного кода, метод GetWeekOfYear не приведен к стандарту ISO 8601 — международному стандарту, выданный организацией ISO (International Organization for Standardization), который описывает формат даты и времени и даёт рекомендации для его использования в международном контексте. Так же согласно ISO 8601 четверг считается четвёртым днём недели, а также днём, который определяет нумерацию недель: первая неделя года определяется как неделя, содержащая первый четверг года, и так далее. Если вы хотите делать все по международным стандартам, предлагаем воспользоваться методом приведенным ниже, в котором внесены корректировки для расчета номера недели.
public int WeekNumber(DateTime fromDate)
{
    // Получаем 1 января указанного нами года
    DateTime startOfYear = fromDate.AddDays(-fromDate.Day + 1).AddMonths(-fromDate.Month + 1);
    // Получение 31 декабря указанного нами года
    DateTime endOfYear = startOfYear.AddYears(1).AddDays(-1);
    //Согласно ISO 8601 четверг считается 
    //четвёртым днём недели, а также днём, 
    //который определяет нумерацию недель: 
    //первая неделя года определяется как неделя, 
    //содержащая первый четверг года, и так далее.
    //Вносим соответствующие корректировки
    int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
    int nds = fromDate.Subtract(startOfYear).Days +
    iso8601Correction[(int)startOfYear.DayOfWeek];
    int wk = nds / 7;
    switch (wk)
    {
        case 0:
            // Возвращаем номер недели от 31 декабря предыдущего года
            return WeekNumber(startOfYear.AddDays(-1));
        case 53:
            // Если 31 декабря выпадает до четверга 1 недели следующего года                    
            if (endOfYear.DayOfWeek < DayOfWeek.Thursday)
                return 1;
            else
                return wk;
        default: return wk;
    }
}
      К примеру в 2004 году 31 декабря выпало на пятницу, и если опираться на стандарт ISO 8601, то количество недель в этом году составило 53.

Ссылки для скачивания примера: Rusfolder.net - DepositFiles - Turbobit.net - Letitbit.net


3 комментария:

  1. 2012, 12, 31 считает как 53 а надо 1 http://www.macmax.ru/calendar/?y=2012&fm=1&lm=12&mc=3&ds=1&wn=2&fd=2&lang=ru

    ОтветитьУдалить
  2. Здравствуйте Егор, спасибо вам за вашу внимательность, в пост были внесены изменения и добавлен новый метод позволяющий корректно рассчитать номер недели в году по международным стандартам.

    ОтветитьУдалить
  3. Не могу понять по какому принципу создавался массив int[] iso8601Correction = { 6, 7, 8, 9, 10, 4, 5 };
    Необходимо сделать точно такую же функцию, но с возможностью выбора дня недели, который бы начинал нумерацию недель года, например, руками выбрать, чтобы первая пятница обозначала первую неделю года.

    ОтветитьУдалить

Большая просьба, не писать в комментариях всякую ерунду не по теме!