はじめに 「年末取得」は“年間ロジックのゴール地点”
年初が「スタートライン」だとしたら、年末は「ゴールライン」です。
年間売上、年間勤怠、年間評価、年間レポート、どれも
「この年はどこからどこまでか」 が決まっていないとロジックが書けません。
C# では、「翌年の年初から1日引く」という考え方で、
どの年でも安全に「年末(12月31日)」を求めることができます。
ここから、
基本の考え方 → ユーティリティ化 → 「今年・昨年・来年」の年末 → 年間期間としての扱い → 会計年度との違い
という流れで、初心者向けにかみ砕いて説明していきます。
基本の考え方:翌年の年初 − 1日 で年末を出す
なぜ「翌年の年初 − 1日」が分かりやすくて安全か
年末はカレンダー上では「12月31日」です。
なので、素直に書くならこうです。
using System;
DateTime any = new DateTime(2026, 5, 10); // 2026/05/10
DateTime yearEnd = new DateTime(any.Year, 12, 31);
Console.WriteLine(yearEnd); // 2026/12/31 0:00:00
C#これでも十分ですが、
「年初とセットで考える」「翌年との境界を意識する」
という意味では、次のように書くほうが“ロジックとしてきれい”です。
DateTime any = new DateTime(2026, 5, 10);
DateTime yearStart = new DateTime(any.Year, 1, 1);
DateTime nextYearStart = yearStart.AddYears(1);
DateTime yearEnd = nextYearStart.AddDays(-1);
Console.WriteLine(yearStart); // 2026/01/01
Console.WriteLine(nextYearStart); // 2027/01/01
Console.WriteLine(yearEnd); // 2026/12/31
C#「年初 → 翌年の年初 → 1日戻す」という流れにしておくと、
“この年の範囲は [年初, 年末] だ” という感覚がコードにそのまま乗ります。
ユーティリティメソッドとしての「年末取得」
任意の日付から年末を求めるメソッド
毎回「年初 → 翌年 → 1日戻す」を手書きするのは面倒なので、
素直にユーティリティにしてしまいましょう。
public static class YearUtil
{
public static DateTime GetYearStart(DateTime date)
{
return new DateTime(date.Year, 1, 1, 0, 0, 0, date.Kind);
}
public static DateTime GetYearEnd(DateTime date)
{
DateTime yearStart = GetYearStart(date);
DateTime nextYearStart = yearStart.AddYears(1);
DateTime yearEnd = nextYearStart.AddDays(-1);
return yearEnd;
}
}
C#使い方はとてもシンプルです。
DateTime d = new DateTime(2026, 5, 10, 15, 30, 0, DateTimeKind.Local);
DateTime yearStart = YearUtil.GetYearStart(d);
DateTime yearEnd = YearUtil.GetYearEnd(d);
Console.WriteLine(yearStart); // 2026/01/01 0:00:00
Console.WriteLine(yearEnd); // 2026/12/31 0:00:00
C#「このメソッドを通せば“その年の年末”が返ってくる」という約束が、
コード上にハッキリ見えるのが大事です。
「今年」「昨年」「来年」の年末を取る
今年の年末
「今年の年末」は、DateTime.Today を基準にすると分かりやすく書けます。
public static class YearUtil
{
public static DateTime GetThisYearEndLocal()
{
DateTime today = DateTime.Today; // Local, 0:00
DateTime yearStart = new DateTime(today.Year, 1, 1, 0, 0, 0, DateTimeKind.Local);
DateTime nextYearStart = yearStart.AddYears(1);
DateTime yearEnd = nextYearStart.AddDays(-1);
return yearEnd;
}
}
C#使い方の例です。
DateTime thisYearEnd = YearUtil.GetThisYearEndLocal();
Console.WriteLine(thisYearEnd); // 2026/12/31 0:00:00
C#昨年・来年の年末
「昨年」「来年」は、年を ±1 するだけです。
public static class YearUtil
{
public static DateTime GetNextYearEndLocal()
{
DateTime today = DateTime.Today;
int nextYear = today.Year + 1;
DateTime yearStart = new DateTime(nextYear, 1, 1, 0, 0, 0, DateTimeKind.Local);
DateTime nextYearStart = yearStart.AddYears(1);
DateTime yearEnd = nextYearStart.AddDays(-1);
return yearEnd;
}
public static DateTime GetPreviousYearEndLocal()
{
DateTime today = DateTime.Today;
int prevYear = today.Year - 1;
DateTime yearStart = new DateTime(prevYear, 1, 1, 0, 0, 0, DateTimeKind.Local);
DateTime nextYearStart = yearStart.AddYears(1);
DateTime yearEnd = nextYearStart.AddDays(-1);
return yearEnd;
}
}
C#使い方の例です。
DateTime thisYear = YearUtil.GetThisYearEndLocal();
DateTime nextYear = YearUtil.GetNextYearEndLocal();
DateTime prevYear = YearUtil.GetPreviousYearEndLocal();
Console.WriteLine(thisYear); // 2026/12/31
Console.WriteLine(nextYear); // 2027/12/31
Console.WriteLine(prevYear); // 2025/12/31
C#「今年の年初/年末」を基準に、
「昨年」「来年」を相対的に扱えるようにしておくと、
年間ロジックがとても書きやすくなります。
年末と「年間期間」のセットで使う
「その年の期間」を [年初, 年末] で表現する
売上・勤怠・評価などの年間集計では、
「この年の期間」をひとまとめで扱いたいことが多いです。
小さな型を用意しておくと、コードがかなり読みやすくなります。
public readonly struct YearRange
{
public DateTime Start { get; }
public DateTime End { get; }
public YearRange(DateTime start, DateTime end)
{
Start = start;
End = end;
}
}
public static class YearUtil
{
public static YearRange GetYearRange(DateTime any)
{
DateTime start = GetYearStart(any);
DateTime end = GetYearEnd(any);
return new YearRange(start, end);
}
}
C#使い方の例です。
DateTime target = new DateTime(2026, 5, 10);
YearRange range = YearUtil.GetYearRange(target);
Console.WriteLine($"開始: {range.Start}"); // 2026/01/01
Console.WriteLine($"終了: {range.End}"); // 2026/12/31
C#この YearRange をそのまま
「今年の売上集計の対象期間」「今年の勤怠集計の対象期間」などに使えるようにしておくと、
年間ロジックのコードがかなり整理されます。
会計年度・事業年度の「年末」との違い
暦年の年末と、会計年度の年末は別物
ここまで話してきた「年末」は、
暦年(カレンダー上の年)の 12/31 の話です。
でも、業務によっては
「会計年度は4月1日〜翌年3月31日」
「事業年度は7月1日〜翌年6月30日」
のように、「年の終わり」が12月31日ではないこともよくあります。
その場合は、
「会計年度の年末取得ユーティリティ」を別で定義するのが安全です。
例えば「4月始まりの会計年度」の年末を求めるなら、
こんなイメージになります。
public static class FiscalYearUtil
{
// 4月始まりの会計年度の年末(3月31日)を求める
public static DateTime GetFiscalYearEnd(DateTime date)
{
int year = date.Year;
// 1〜3月は「その年の3月31日」が会計年度の年末
// 4〜12月は「翌年の3月31日」が会計年度の年末
if (date.Month >= 4)
{
year += 1;
}
return new DateTime(year, 3, 31, 0, 0, 0, date.Kind);
}
}
C#暦年の年末(12/31)と、
会計年度の年末(3/31 など)は、
別物としてユーティリティを分けるのがポイントです。
UTCとローカル、どの時間軸の年末を扱うか
「どのタイムゾーンの“年末”か」を意識する
年末も、UTCとローカルで意味が変わります。
例えば、「日本時間での今年の年末」を基準にしたい場合は、
まずUTCから日本時間に変換してから年末を取る、という流れになります。
using System;
public static class YearUtil
{
public static DateTime GetThisYearEndJstFromUtcNow()
{
DateTime utcNow = DateTime.UtcNow;
TimeZoneInfo jst = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTime nowJst = TimeZoneInfo.ConvertTimeFromUtc(utcNow, jst);
DateTime yearStartJst = new DateTime(nowJst.Year, 1, 1, 0, 0, 0, DateTimeKind.Unspecified);
DateTime nextYearStartJst = yearStartJst.AddYears(1);
DateTime yearEndJst = nextYearStartJst.AddDays(-1);
return yearEndJst;
}
}
C#「どのタイムゾーンの年末か」をユーティリティ名やコメントに明示しておくと、
後から読んだ人が迷わずに済みます。
まとめ 「年末取得ユーティリティ」は“年間ロジックの終点を固定するもの」
年末取得は、
年間売上、年間勤怠、年間評価、年間レポートなど、
「1年単位で考えるロジック」の終点を決めるための重要なピースです。
押さえておきたいポイントは、次のようなイメージです。
- 任意の日付の年末は「その年の年初 → 翌年の年初 → 1日戻す」で安全に求められる。
- 「今年」「昨年」「来年」の年末は、
Today.Yearを基準に ±1 して組み立てると分かりやすい。 - 年初と年末をセットにした「年間期間」型(
YearRangeなど)を用意しておくと、集計やレポートのコードが読みやすくなる。 - 会計年度・事業年度など、「年の終わりが12月31日ではない」ケースは、専用のユーティリティ(
FiscalYearUtilなど)として分けて設計する。 - UTC基準かローカル基準か(どのタイムゾーンの年末か)を意識し、ユーティリティ名にもそれを反映しておくと安全。
ここを押さえておくと、
「その場しのぎで年をいじっている」状態から一歩進んで、
“年間ロジックの始点(年初)と終点(年末)をきれいに定義した、実務で使える日付・時間ユーティリティ”を
自分のC#コードの中に自然に組み込めるようになっていきます。
