はじめに 「年初取得」は“年間ロジックのスタートライン”
月初・月末が「月次処理の基準点」だとしたら、
年初は「年間処理の基準点」です。
例えば、
「今年の売上集計」「今年の有給残高」「今年度の評価期間」
こういうロジックを書くときに、
“この日付が属する年の、1月1日” をサッと取れるかどうかで、コードの見通しがかなり変わります。
C# では、DateTime の Year を使ってnew DateTime(year, 1, 1, …) を作る、というシンプルな考え方で実現できます。
ここから、
基本の年初取得 → ユーティリティ化 → 「今年・昨年・来年」の年初 → 会計年度との違い → UTC/ローカルの意識
という流れで、初心者向けにかみ砕いて説明していきます。
基本の考え方:年と「1月1日」から年初を作る
どんな日付でも「その年の1月1日」にそろえる
まずは、ある DateTime が与えられたときに、
「その日付が属する年の年初(1月1日)」を求める一番基本的な方法です。
using System;
DateTime any = new DateTime(2026, 5, 10, 15, 30, 0); // 2026/05/10 15:30
DateTime yearStart = new DateTime(any.Year, 1, 1);
Console.WriteLine(any); // 2026/05/10 15:30:00
Console.WriteLine(yearStart); // 2026/01/01 0:00:00
C#ポイントは、any.Year をそのまま使い、
月を 1、日を 1 に固定して new DateTime(year, 1, 1) を作ることです。
これで「その年の1月1日 0:00:00」の DateTime が得られます。
「今年の集計は 1/1 から始まる」という前提なら、
この年初を基準に「今年の期間」を組み立てていくことができます。
ユーティリティメソッドとしての「年初取得」
任意の日付から年初を求めるメソッド
毎回 new DateTime(d.Year, 1, 1) と書いてもいいのですが、
「これは年初を取っているんだ」と一目で分かるように、
ユーティリティメソッドにしてしまうのがおすすめです。
public static class YearUtil
{
public static DateTime GetYearStart(DateTime date)
{
return new DateTime(date.Year, 1, 1, 0, 0, 0, date.Kind);
}
}
C#ここでは、Kind(Local / Utc / Unspecified)を引き継ぎつつ、
時刻は 0:00:00 にそろえています。
使い方はとてもシンプルです。
DateTime d = new DateTime(2026, 5, 10, 15, 30, 0, DateTimeKind.Local);
DateTime yearStart = YearUtil.GetYearStart(d);
Console.WriteLine(yearStart); // 2026/01/01 0:00:00 (Local)
C#「このメソッドを通せば“その年の年初”が返ってくる」という約束が、
コード上にハッキリ見えるのが大事です。
「今年」「昨年」「来年」の年初を取る
今年の年初
「今年の年初」は、DateTime.Today を使うと分かりやすく書けます。
public static class YearUtil
{
public static DateTime GetThisYearStartLocal()
{
DateTime today = DateTime.Today; // Local, 0:00
return new DateTime(today.Year, 1, 1, 0, 0, 0, DateTimeKind.Local);
}
}
C#使い方の例です。
DateTime thisYearStart = YearUtil.GetThisYearStartLocal();
Console.WriteLine(thisYearStart); // 2026/01/01 0:00:00
C#昨年・来年の年初
「昨年」「来年」は、年を ±1 するだけです。
public static class YearUtil
{
public static DateTime GetThisYearStartLocal()
{
DateTime today = DateTime.Today;
return new DateTime(today.Year, 1, 1, 0, 0, 0, DateTimeKind.Local);
}
public static DateTime GetNextYearStartLocal()
{
DateTime today = DateTime.Today;
return new DateTime(today.Year + 1, 1, 1, 0, 0, 0, DateTimeKind.Local);
}
public static DateTime GetPreviousYearStartLocal()
{
DateTime today = DateTime.Today;
return new DateTime(today.Year - 1, 1, 1, 0, 0, 0, DateTimeKind.Local);
}
}
C#使い方の例です。
DateTime thisYear = YearUtil.GetThisYearStartLocal();
DateTime nextYear = YearUtil.GetNextYearStartLocal();
DateTime prevYear = YearUtil.GetPreviousYearStartLocal();
Console.WriteLine(thisYear); // 2026/01/01
Console.WriteLine(nextYear); // 2027/01/01
Console.WriteLine(prevYear); // 2025/01/01
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);
DateTime yearStart = YearUtil.GetYearStart(d);
DateTime yearEnd = YearUtil.GetYearEnd(d);
Console.WriteLine(yearStart); // 2026/01/01
Console.WriteLine(yearEnd); // 2026/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 を
「今年の売上集計の対象期間」「今年の勤怠集計の対象期間」などにそのまま使えるようにしておくと、
年間ロジックのコードがかなり整理されます。
会計年度・事業年度との違いに注意する
「年初=1月1日」とは限らない世界
ここまで話してきた「年初」は、
暦年(カレンダー上の年)の話です。
でも、業務によっては
「会計年度は4月1日スタート」
「事業年度は7月1日スタート」
のように、「年の始まり」が1月1日ではないこともよくあります。
その場合は、
「会計年度の年初取得ユーティリティ」を別で定義するのが安全です。
例えば「4月始まりの会計年度」の年初を求めるなら、
こんなイメージになります。
public static class FiscalYearUtil
{
// 4月始まりの会計年度の年初を求める
public static DateTime GetFiscalYearStart(DateTime date)
{
int year = date.Year;
// 1〜3月は「前の年の4月1日」が会計年度の年初
if (date.Month < 4)
{
year -= 1;
}
return new DateTime(year, 4, 1, 0, 0, 0, date.Kind);
}
}
C#暦年の年初(1月1日)と、
会計年度の年初(4月1日など)は、
別物としてユーティリティを分けるのがポイントです。
UTCとローカル、どの時間軸の年初を扱うか
「どのタイムゾーンの“年初”か」を意識する
年初も、UTCとローカルで意味が変わります。
例えば、「日本時間での今年の年初」を基準にしたい場合は、
まずUTCから日本時間に変換してから年初を取る、という流れになります。
using System;
public static class YearUtil
{
public static DateTime GetThisYearStartJstFromUtcNow()
{
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);
return yearStartJst;
}
}
C#「どのタイムゾーンの年初か」をユーティリティ名やコメントに明示しておくと、
後から読んだ人が迷わずに済みます。
まとめ 「年初取得ユーティリティ」は“年間ロジックの基準点”
年初取得は、
年間売上、年間勤怠、年間評価、年間レポートなど、
「1年単位で考えるロジック」の基準点になります。
押さえておきたいポイントは、次のようなイメージです。
- 任意の日付の年初は
new DateTime(date.Year, 1, 1, …)で作れる。 - 「今年」「昨年」「来年」の年初は、
Today.Yearを基準に ±1 して組み立てると分かりやすい。 - 年初と年末をセットにした「年間期間」型(
YearRangeなど)を用意しておくと、集計やレポートのコードが読みやすくなる。 - 会計年度・事業年度など、「年の始まりが1月1日ではない」ケースは、専用のユーティリティ(
FiscalYearUtilなど)として分けて設計する。 - UTC基準かローカル基準か(どのタイムゾーンの年初か)を意識し、ユーティリティ名にもそれを反映しておくと安全。
ここを押さえておくと、
「その場しのぎで年をいじっている」状態から一歩進んで、
“年間ロジックの基準点をきれいに定義した、実務で使える日付・時間ユーティリティ”を
自分のC#コードの中に自然に組み込めるようになっていきます。
