Вычислить DateTime недель в строках

В настоящее время я пишу небольшой календарь на ASP.Net C#. В настоящее время для создания строк недель я делаю следующее для цикла:

var iWeeks = 6;
for (int w = 0; w < iWeeks; w++) {

Это работает нормально, однако в некоторых месяцах будет всего 5 недель, а в некоторых редких случаях - 4.

Как я могу рассчитать количество строк, которые потребуются в конкретном месяце?

Это пример того, что я создаю:

введите описание изображения здесь

Однако, как вы можете видеть для указанного выше месяца, требуется всего 5 строк. Возьмем этот месяц (август 2008 г.), который начинается в субботу и заканчивается в понедельник 6-й недели / ряда.

Изображение найдено в Google


Это пример того, что я создаю:

введите описание изображения здесь

Однако, как вы можете видеть для указанного выше месяца, требуется всего 5 строк. Возьмем этот месяц (август 2008 г.), который начинается в субботу и заканчивается в понедельник 6-й недели / ряда.

Изображение найдено в Google

Ответов (9)

Решение

Вот способ, который это делает:

public int GetWeekRows(int year, int month)
{
    DateTime firstDayOfMonth = new DateTime(year, month, 1);
    DateTime lastDayOfMonth = new DateTime(year, month, 1).AddMonths(1).AddDays(-1);
    System.Globalization.Calendar calendar = System.Threading.Thread.CurrentThread.CurrentCulture.Calendar;
    int lastWeek = calendar.GetWeekOfYear(lastDayOfMonth, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    int firstWeek = calendar.GetWeekOfYear(firstDayOfMonth, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    return lastWeek - firstWeek + 1;
}

Вы можете настроить правило календарной недели, изменив часть System.Globalization.CalendarWeekRule.FirstFourDayWeek. Я надеюсь, что код не требует пояснений.

вы можете получить дни месяца, используя DateTime.DaysInMonth (int WhichYear, int WhichMonth);

Проверьте Calendar.GetWeekOfYear . Это должно сработать.

С этим есть проблема, он не соответствует правилу 4 дней по ISO 8601, но в остальном это аккуратно.

Как насчет проверки, на какой неделе будут первые и последние дни?

Месяцы в юлианском / григорианском календаре имеют одинаковое количество дней в году, за исключением февраля, который может иметь 28 или 29 дней в зависимости от високосности года. Вы можете найти количество дней в разделе «Описание» на http://en.wikipedia.org/wiki/Gregorian_calendar .

Как упоминал @darkdog, у вас есть DateTime.DaysInMonth. Просто сделай это:

var days = DateTime.DaysInMonth(year, month) + 
           WhatDayOfWeekTheMonthStarts(year, month);    
int rows = (days / 7);  
if (0 < days % 7)  
{  
    ++rows;
}  

Примите во внимание тот факт, что для целей глобализации / локализации в некоторых частях мира используются разные календари / методы организации года.

Попробуй это,

DateTime.DaysInMonth

Сначала узнайте, в какой день недели находится первый день месяца. Просто установите datetime с первым днем, всегда 1, а также с соответствующим годом и месяцем, в нем есть свойство дня недели.

Затем отсюда вы можете использовать количество дней в месяце DateTime.DaysInMonth, чтобы определить, сколько недель вы разделите на семь, а затем сложите количество дней из 1, на которое выпадает ваш первый день. Например,

public static int RowsForMonth(int month, int year)
{
    DateTime first = new DateTime(year, month, 1);

    //number of days pushed beyond monday this one sits
    int offset = ((int)first.DayOfWeek) - 1;

    int actualdays = DateTime.DaysInMonth(month, year) +  offset;

    decimal rows = (actualdays / 7);
    if ((rows - ((int)rows)) > .1)
    {
        rows++;
    }
    return rows;
}

Что ж, это зависит от культуры, которую вы используете, но предположим, что вы можете использовать Thread.CurrentThread.CurrentCulture, тогда код для получения текущей недели будет следующим:

Culture culture = Thread.CurrentThread.CurrentCulture;
Calendar cal = culture.Calendar;
Int32 week = cal.GetWeekOfYear(DateTime.Today,
    culture.DateTimeFormat.CalendarWeekRule,
    culture.DateTimeFormat.FirstDayOfWeek);

Проблема не в количестве дней в месяце, а в том, сколько недель он длится.

В феврале в невисокосном году будет 28 дней, и если первый день месяца - понедельник, февраль будет охватывать ровно 4 недели.

Однако, если первый день месяца - вторник или любой другой день недели, февраль будет охватывать 5 номеров недель.

Таким же образом 31-дневный месяц может охватывать 5 или 6 недель. Если месяц начинается в понедельник, 31 день дает вам 5 номеров недель. Если месяц начинается в субботу или воскресенье, он будет охватывать 6 номеров недель.

Итак, правильный способ получить это число - найти номер недели первого и последнего дней месяца.


Редактировать # 1 : Вот как рассчитать количество недель в течение данного месяца: Редактировать # 2 : Исправлены ошибки в коде

public static Int32 GetWeekForDateCurrentCulture(DateTime dt)
{
    CultureInfo culture = Thread.CurrentThread.CurrentCulture;
    Calendar cal = culture.Calendar;
    return cal.GetWeekOfYear(dt,
        culture.DateTimeFormat.CalendarWeekRule,
        culture.DateTimeFormat.FirstDayOfWeek);
}

public static Int32 GetWeekSpanCountForMonth(DateTime dt)
{
    DateTime firstDayInMonth = new DateTime(dt.Year, dt.Month, 1);
    DateTime lastDayInMonth = firstDayInMonth.AddMonths(1).AddDays(-1);
    return
        GetWeekForDateCurrentCulture(lastDayInMonth)
        - GetWeekForDateCurrentCulture(firstDayInMonth)
        + 1;
}