C# Tips | 日付・時間処理:年末取得

C# C#
スポンサーリンク

はじめに 「年末取得」は“年間ロジックのゴール地点”

年初が「スタートライン」だとしたら、年末は「ゴールライン」です。
年間売上、年間勤怠、年間評価、年間レポート、どれも
「この年はどこからどこまでか」 が決まっていないとロジックが書けません。

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#コードの中に自然に組み込めるようになっていきます。

タイトルとURLをコピーしました