C# Tips | 日付・時間処理:週番号取得

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

はじめに 「週番号取得」は“時間をざっくり区切るためのラベル付け”

「この売上は何週目のデータ?」「週次レポートの第何週?」「ISO週番号でログを集計したい」
こういう“週単位”の集計やレポートを作るときに必要になるのが「週番号」です。

C# では、Calendar クラスを使って「その日付が年の第何週か」を取得できます。
ただし、「週の始まりは何曜日か」「1週目の定義は?」「ISO週番号か?」といったルールを決めないと、
同じ日付でも“何週目か”が変わってしまいます。

ここでは、
基本の GetWeekOfYear の使い方から、
日本のカレンダーっぽい週番号、ISO週番号、実務でのユーティリティ化まで、
初心者向けにかみ砕いて説明していきます。


基本:Calendar.GetWeekOfYear で週番号を取得する

一番シンプルな週番号取得

週番号を取るための中核は、System.Globalization.CalendarGetWeekOfYear メソッドです。

using System;
using System.Globalization;

DateTime date = new DateTime(2026, 2, 10);

CultureInfo culture = CultureInfo.CurrentCulture;
Calendar calendar = culture.Calendar;

CalendarWeekRule weekRule = culture.DateTimeFormat.CalendarWeekRule;
DayOfWeek firstDayOfWeek = culture.DateTimeFormat.FirstDayOfWeek;

int week = calendar.GetWeekOfYear(date, weekRule, firstDayOfWeek);

Console.WriteLine($"{date:yyyy-MM-dd} は {week} 週目です。");
C#

ここで重要なのは、GetWeekOfYear が3つの情報を必要としていることです。

  • どの日付か(date
  • 週番号のルール(CalendarWeekRule
  • 週の始まりの曜日(DayOfWeek

この「ルール」と「週の始まり」をどう決めるかで、週番号の意味が変わります。


週番号のルールを理解する:CalendarWeekRule

代表的な3つのルール

CalendarWeekRule には主に3つの値があります。

FirstDay

「年の最初の週は、その年の最初の曜日を含む週」とするルールです。
例えば「週の始まりが日曜日」の場合、
1月1日が何曜日であっても、その週が第1週になります。

FirstFullWeek

「年の最初の週は、その年の最初の曜日で始まる“最初の完全な週”」というルールです。
例えば「週の始まりが日曜日」の場合、
その年で最初に迎える“日曜〜土曜が全部その年に入っている週”が第1週になります。

FirstFourDayWeek

「年の最初の週は、その年の日が4日以上含まれる最初の週」というルールです。
これは ISO 週番号の定義に近い考え方で、
「1月4日を含む週が第1週」と言い換えることもできます。

この CalendarWeekRule と「週の始まりの曜日」を組み合わせて、
「自分のシステムでは週番号をこう定義する」と決めるのが大事です。


日本のカレンダーっぽい「日曜始まり・FirstDay」の週番号

いわゆる“カレンダーアプリの週番号”に近い形

日本の一般的なカレンダーは「日曜始まり」が多いので、
それに近い感覚で週番号を付けたいなら、
FirstDayDayOfWeek.Sunday の組み合わせが分かりやすいです。

using System;
using System.Globalization;

public static class WeekNumberUtil
{
    public static int GetWeekNumber_SundayFirst_FirstDay(DateTime date)
    {
        Calendar calendar = CultureInfo.InvariantCulture.Calendar;

        CalendarWeekRule rule = CalendarWeekRule.FirstDay;
        DayOfWeek firstDay = DayOfWeek.Sunday;

        return calendar.GetWeekOfYear(date, rule, firstDay);
    }
}
C#

使い方の例です。

DateTime d1 = new DateTime(2026, 1, 1);  // 木曜日
DateTime d2 = new DateTime(2026, 1, 3);  // 土曜日
DateTime d3 = new DateTime(2026, 1, 4);  // 日曜日

Console.WriteLine(WeekNumberUtil.GetWeekNumber_SundayFirst_FirstDay(d1)); // 1
Console.WriteLine(WeekNumberUtil.GetWeekNumber_SundayFirst_FirstDay(d2)); // 1
Console.WriteLine(WeekNumberUtil.GetWeekNumber_SundayFirst_FirstDay(d3)); // 2
C#

1月1日が木曜日でも、その週(日〜土)が「第1週」となり、
次の日曜日から始まる週が「第2週」になります。

「カレンダーの行番号」のような感覚で週を扱いたい場合は、
このルールが直感的です。


ISO週番号(ISO 8601)を取得する

「週の始まりは月曜」「1月4日を含む週が第1週」

国際的なシステムやログ集計では、
「ISO週番号(ISO 8601)」を使うことがよくあります。

ISO週番号のざっくりしたルールはこうです。

  • 週の始まりは月曜日
  • 1月4日を含む週が第1週
  • その結果、年の最初の数日は前年の最終週になることもある

C# で ISO週番号を出すには、
CalendarWeekRule.FirstFourDayWeekDayOfWeek.Monday を使います。

using System;
using System.Globalization;

public static class IsoWeekNumberUtil
{
    public static int GetIsoWeekOfYear(DateTime date)
    {
        Calendar calendar = CultureInfo.InvariantCulture.Calendar;

        CalendarWeekRule rule = CalendarWeekRule.FirstFourDayWeek;
        DayOfWeek firstDay = DayOfWeek.Monday;

        return calendar.GetWeekOfYear(date, rule, firstDay);
    }
}
C#

使い方の例です。

DateTime d1 = new DateTime(2026, 1, 1);  // 木
DateTime d2 = new DateTime(2026, 1, 4);  // 日
DateTime d3 = new DateTime(2026, 1, 5);  // 月

Console.WriteLine(IsoWeekNumberUtil.GetIsoWeekOfYear(d1)); // 1 か 52/53 になるケースもあり得る
Console.WriteLine(IsoWeekNumberUtil.GetIsoWeekOfYear(d2));
Console.WriteLine(IsoWeekNumberUtil.GetIsoWeekOfYear(d3));
C#

ISO週番号では、
「年の最初の数日が前年の最終週に属する」ことがあるため、
date.Year と「週番号の属する年」が一致しないこともあります。

厳密な ISO週番号(週番号だけでなく“ISO週年”も含めて扱う)には、
.NET 6 以降なら System.Globalization.ISOWeek クラスを使うのが一番確実です。

using System.Globalization;

int isoWeek = ISOWeek.GetWeekOfYear(date);
int isoYear = ISOWeek.GetYear(date);
C#

この ISOWeek は、
「この日付は ISO でいうと何年の第何週か」を正しく計算してくれます。


実務で使える「週番号ユーティリティ」の形

ルールを“名前で固定する”のが大事

週番号は「ルール次第で結果が変わる」ので、
実務では「どのルールか」をメソッド名に刻んでおくのがとても大事です。

例えば、次のようなユーティリティクラスを用意できます。

using System;
using System.Globalization;

public static class WeekNumberHelper
{
    private static readonly Calendar InvariantCalendar = CultureInfo.InvariantCulture.Calendar;

    public static int GetWeek_SundayFirst_FirstDay(DateTime date)
    {
        return InvariantCalendar.GetWeekOfYear(
            date,
            CalendarWeekRule.FirstDay,
            DayOfWeek.Sunday);
    }

    public static int GetWeek_MondayFirst_FirstFourDayWeek(DateTime date)
    {
        return InvariantCalendar.GetWeekOfYear(
            date,
            CalendarWeekRule.FirstFourDayWeek,
            DayOfWeek.Monday);
    }

    public static int GetIsoWeek(DateTime date)
    {
        return ISOWeek.GetWeekOfYear(date);
    }

    public static int GetIsoWeekYear(DateTime date)
    {
        return ISOWeek.GetYear(date);
    }
}
C#

使い方のイメージです。

DateTime date = new DateTime(2026, 1, 2);

int w1 = WeekNumberHelper.GetWeek_SundayFirst_FirstDay(date);
int w2 = WeekNumberHelper.GetWeek_MondayFirst_FirstFourDayWeek(date);
int isoWeek = WeekNumberHelper.GetIsoWeek(date);
int isoYear = WeekNumberHelper.GetIsoWeekYear(date);

Console.WriteLine($"日曜始まり・FirstDay: {w1} 週");
Console.WriteLine($"月曜始まり・FirstFourDayWeek: {w2} 週");
Console.WriteLine($"ISO週: {isoYear}-W{isoWeek:D2}");
C#

ここでの重要ポイントは、
「ルールの違いをメソッド名にそのまま書く」ことです。
これをやっておくと、後からコードを読んだときに、
「この週番号はどういう定義なのか」が一目で分かります。


実務での注意点1:カルチャに依存させるか、固定するか

CurrentCulture に任せると環境で結果が変わる

最初の例では CultureInfo.CurrentCulture を使いましたが、
これは「実行環境のカルチャ」に依存します。

開発者のPC、日本のサーバー、海外のサーバーなどでカルチャが違うと、
週の始まりや週番号のルールが変わってしまう可能性があります。

業務システムでは、

  • 「日本のルールで固定する」
  • 「ISO週で固定する」

など、カルチャに依存しないルールを決めて、
CultureInfo.InvariantCultureISOWeek を使うほうが安全です。


実務での注意点2:週番号だけでは“どの年の何週か”が曖昧になる

「2026年の第1週」なのか「ISOでいう2025年の第1週」なのか

ISO週番号では、
「2026/01/01 が ISO では 2025年の第53週」
のようなケースが普通にあります。

そのため、

  • date.Year と ISO週の“年”は一致しないことがある
  • 「週番号だけ」ではどの年の週か分からない

という点に注意が必要です。

ISO週番号を使うときは、

  • ISOWeek.GetYear(date) で“ISO週年”も一緒に持つ
  • 表示は「2025-W53」のように「年+週」でセットにする

といったルールにしておくと、誤解が減ります。


まとめ 「週番号取得ユーティリティ」は“週の定義をコードに刻むもの」

週番号取得は、一見 GetWeekOfYear を呼ぶだけですが、
その裏には「週の始まり」「1週目の定義」「ISOかどうか」といったルールが潜んでいます。

押さえておきたいポイントを整理すると、こうなります。

  • 週番号は Calendar.GetWeekOfYear(date, rule, firstDayOfWeek) で取得する
  • CalendarWeekRule と「週の始まりの曜日」の組み合わせで意味が大きく変わる
  • 日本のカレンダーっぽくするなら「日曜始まり+FirstDay」、国際的なISO週なら「月曜始まり+FirstFourDayWeek」や ISOWeek を使う
  • 実務では「どのルールか」をメソッド名に刻んだユーティリティを用意し、カルチャ依存を避ける
  • ISO週番号では「週の年」と date.Year が一致しないことがあるので、「年+週」をセットで扱う

ここを押さえておけば、
「なんとなく週番号を取っている」状態から一歩進んで、
“ビジネスで使う週の定義をきちんとコードに刻み込んだ、実務で使える週番号取得ユーティリティ”を
自分の C# プロジェクトに自信を持って組み込めるようになります。

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