質問
私は現在、ASP.Net C# で小さなカレンダーを作成しています。現在、週の行を生成するには、次の for ループを実行します。
var iWeeks = 6;
for (int w = 0; w < iWeeks; w++) {
これは問題ありませんが、月によっては 5 週間しか持たず、まれに 4 週間になることもあります。
特定の月に必要な行数を計算するにはどうすればよいですか?
これは私が作成しているものの例です。
ただし、上記の月でわかるように、必要な行は 5 行だけです。今月 (2008 年 8 月) は、6 週目/行の土曜日に始まり月曜日に終わります。
グーグルで見つけた画像
これは私が作成しているものの例です。
ただし、上記の月でわかるように、必要な行は 5 行だけです。今月 (2008 年 8 月) は、6 週目/行の土曜日に始まり月曜日に終わります。
グーグルで見つけた画像
解決
それを行うメソッドは次のとおりです。
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 部分を変更することで、暦週ルールをカスタマイズできます。コードが一目瞭然であることを願っています。
他のヒント
これは使用しているカルチャによって異なりますが、Thread.CurrentThread.CurrentCulture を使用できると仮定します。その場合、今日の週を取得するコードは次のようになります。
Culture culture = Thread.CurrentThread.CurrentCulture;
Calendar cal = culture.Calendar;
Int32 week = cal.GetWeekOfYear(DateTime.Today,
culture.DateTimeFormat.CalendarWeekRule,
culture.DateTimeFormat.FirstDayOfWeek);
初日と最終日が何週目になるのか確認してみてはいかがでしょうか?
チェック Calendar.GetWeekOf Year. 。それはうまくいくはずです。
ISO 8601 による 4 日ルールに従っていないという問題がありますが、それ以外は問題ありません。
DateTime.DaysInMonth(int Whichyear,int WhichMonth); を使用して月の日数を取得できます。
ユリウス暦/グレゴリオ暦の月の日数は毎年同じですが、2 月はその年のうるう数に応じて 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;
}
グローバリゼーション/ローカリゼーションの目的で、世界の一部の地域では異なるカレンダー/年の編成方法が使用されているという事実を考慮してください。
問題は月の日数ではなく、それが何週間にわたるかです。
うるう年ではない年の 2 月は 28 日あり、月の最初の日が月曜日の場合、2 月はちょうど 4 週になります。
ただし、月の最初の日が火曜日または他の曜日の場合、2 月は 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;
}
これを試して、
DateTime.DaysInMonth
まず、月の最初の日が何曜日であるかを調べます。最初の日 (常に 1) と、問題の年と月を含む datetime を新しく作成するだけで、そこには曜日のプロパティがあります。
ここから、その月の日数を使用できます。 DateTime.DaysInMonth
, 7 で割って、最初の日が 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;
}