Рассчитать недели DateTime в ряды - PullRequest
7 голосов
/ 13 августа 2008

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

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

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

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

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

enter image description here

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

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


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

enter image description here

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

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

Ответы [ 9 ]

6 голосов
/ 13 августа 2008

Вот метод, который делает это:

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. Я надеюсь, что код не требует пояснений.

2 голосов
/ 13 августа 2008

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

Culture culture = Thread.CurrentThread.CurrentCulture;
Calendar cal = culture.Calendar;
Int32 week = cal.GetWeekOfYear(DateTime.Today,
    culture.DateTimeFormat.CalendarWeekRule,
    culture.DateTimeFormat.FirstDayOfWeek);
0 голосов
/ 13 августа 2008

Первый Узнайте, в каком из дней недели находится первый день месяца. Просто добавьте дату и время с первым днем, всегда 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;
}
0 голосов
/ 13 августа 2008

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

Февраль в не високосном году будет иметь 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;
}
0 голосов
/ 13 августа 2008

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

0 голосов
/ 13 августа 2008

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

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

0 голосов
/ 13 августа 2008

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

DateTime.DaysInMonth
0 голосов
/ 13 августа 2008

Месяцы в юлианском / григорианском календаре имеют одинаковое количество дней в году, за исключением февраля, который может иметь 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;
}  

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

0 голосов
/ 13 августа 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...