はじめに:「月日数取得」は“カレンダー計算の出発点”
「今月は何日まである?」「締め日は月末」「2月の最終営業日」
こういう処理をちゃんと書こうとすると、必ず必要になるのが「その月が何日まであるか」です。
特に 2 月は、閏年かどうかで 28 日か 29 日かが変わるので、
「自分で 30,31 を決め打ちする」ようなコードは一気に危険になります。
C# には、この問題を一発で解決してくれるメソッドが用意されています。
そこからスタートして、「どう使うか」「どうユーティリティ化するか」をかみ砕いて見ていきましょう。
基本形:DateTime.DaysInMonth を使えば一発で取れる
year と month を渡すだけで、その月の日数が返ってくる
C# では、System.DateTime に次の静的メソッドがあります。
int days = DateTime.DaysInMonth(2026, 2); // 2026年2月の日数
C#これだけで、
「その年のその月が何日まであるか」を整数で返してくれます。
少し例を増やしてみます。
Console.WriteLine(DateTime.DaysInMonth(2026, 1)); // 31
Console.WriteLine(DateTime.DaysInMonth(2026, 2)); // 28(2026年は平年)
Console.WriteLine(DateTime.DaysInMonth(2024, 2)); // 29(2024年は閏年)
Console.WriteLine(DateTime.DaysInMonth(2026, 4)); // 30
C#ここでの重要ポイントは、
「閏年かどうかも含めて、全部 DaysInMonth が面倒を見てくれる」ことです。
自分で「2月だけ if で分岐して 28 or 29」とか書く必要はありません。
ユーティリティ化:DateTime から「その月の日数」を取る
DateTime を渡したら、その月の日数を返すメソッド
業務コードでは、DateTime をすでに持っていることが多いので、
「DateTime を渡したら、その月の日数を返す」ユーティリティを作っておくと便利です。
public static class MonthUtil
{
public static int GetDaysInMonth(DateTime date)
{
return DateTime.DaysInMonth(date.Year, date.Month);
}
}
C#使い方の例です。
DateTime d1 = new DateTime(2026, 2, 10);
int days1 = MonthUtil.GetDaysInMonth(d1); // 28
DateTime d2 = new DateTime(2024, 2, 10);
int days2 = MonthUtil.GetDaysInMonth(d2); // 29
Console.WriteLine(days1);
Console.WriteLine(days2);
C#ここでの重要ポイントは、
「DateTime から Year と Month だけを取り出して DaysInMonth に渡す」
という“分解の一手間”をユーティリティ側に隠していることです。
呼び出し側は「その日付が属する月の日数」を意識するだけで済みます。
月末日を求める:締め処理でよく使うパターン
「その月の最終日」を DateTime で取得する
「月末締め」「月末日を表示したい」といったときには、
「その月の日数」から「月末日(DateTime)」を作るのが定番です。
public static DateTime GetEndOfMonth(DateTime date)
{
int days = DateTime.DaysInMonth(date.Year, date.Month);
return new DateTime(date.Year, date.Month, days);
}
C#使い方の例です。
DateTime d1 = new DateTime(2026, 2, 10);
DateTime end1 = GetEndOfMonth(d1); // 2026-02-28
DateTime d2 = new DateTime(2024, 2, 10);
DateTime end2 = GetEndOfMonth(d2); // 2024-02-29
Console.WriteLine(end1);
Console.WriteLine(end2);
C#ここでの重要ポイントは、
「DaysInMonth の結果をそのまま day に入れて new DateTime(year, month, day) すれば、
その月の“最終日”が作れる」ことです。
これで「2月だけ特別扱いする」ようなコードを書かずに済みます。
月日数を使ったバリデーション:存在しない日付を弾く
「年・月・日」がバラバラに来たときのチェック
画面から「年」「月」「日」が別々に送られてくるケースでは、
「その組み合わせが実在する日付かどうか」をチェックしたくなります。
DaysInMonth を使うと、シンプルに書けます。
public static bool IsValidDate(int year, int month, int day)
{
if (month < 1 || month > 12)
return false;
int daysInMonth = DateTime.DaysInMonth(year, month);
return day >= 1 && day <= daysInMonth;
}
C#使い方の例です。
Console.WriteLine(IsValidDate(2026, 2, 28)); // true
Console.WriteLine(IsValidDate(2026, 2, 29)); // false
Console.WriteLine(IsValidDate(2024, 2, 29)); // true
Console.WriteLine(IsValidDate(2026, 4, 31)); // false(4月は30日まで)
C#ここでの重要ポイントは、
「月ごとの日数(閏年含む)を DaysInMonth に任せることで、
自分は“1〜その月の日数の範囲に収まっているか”だけを見ればよくなる」ことです。
バリデーションロジックがかなりスッキリします。
実務で意識してほしいポイント
「決め打ちの 30/31/28/29 ロジック」を書かない
ありがちなアンチパターンは、
「1,3,5,7,8,10,12 は 31 日」「4,6,9,11 は 30 日」「2 月は 28 or 29」
を自前で if 文に書いてしまうことです。
一見正しそうですが、
2月の閏年判定を間違える
将来、暦の扱いが変わったときに追従できない
テスト漏れが起きやすい
など、リスクが高くなります。
DateTime.DaysInMonth は、
すでに .NET の中で十分にテストされている信頼できる実装なので、
「月日数取得はまずこれを使う」と決めてしまうのが実務的です。
「月末」「月初」「月日数」はセットでユーティリティ化しておくと強い
月日数取得を起点に、
その月の日数(DaysInMonth)
その月の月末日(GetEndOfMonth)
その月の月初日(new DateTime(year, month, 1))
をセットでユーティリティ化しておくと、
締め処理・集計処理・レポート出力など、
“月単位”のロジックがとても書きやすくなります。
まとめ:「月日数取得ユーティリティ」は“カレンダーを正しく扱うための土台”
月日数取得の本質は、
「その年のその月が何日まであるか」を、
安全に・一貫して求められるようにすることです。
C# では、
DateTime.DaysInMonth(year, month) を使えば、閏年も含めて正しい日数が一発で取れる。DateTime を渡すユーティリティにしておくと、「その日付が属する月の日数」を簡単に扱える。
月末日を求める・日付バリデーションをするなど、月日数取得を起点にした実務処理がたくさん書ける。
このあたりを押さえておけば、
「2月だけ特別扱いしてバグる」コードから卒業して、
“カレンダーに強い C# ユーティリティ”を自信を持って書けるようになります。
