0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

.NETで、ISO 8601の週番号を使うならISOWeekクラスを使う

Posted at

3行まとめ

  • .NETで、ISO 8601の週番号を扱いたい場合、ISOWeekクラスを使えばOK
  • ISOWeekクラスには、.NET 10で、DateOnlyのメソッド・オーバーロードが追加予定
  • .NET 9において、週番号に対応した書式指定子はない。.NET 10 preview 1段階でもなさそう

※ 本投稿では、「ISO 8601」の週に関してのみを対象とします。
※ 本投稿は、明記しない場合.NET 9時点の情報について基づいて作成しています。
※ 本投稿は、一部.NET 10 Preview 1の情報を含みます。正式リリース前に変更の可能性がある点に注意してください。

前提

ISO 8601は、日付、時刻、継続時間を規定する国際規格です。

このISO 8601の中で、「その年の第何週」というものが定められています。

  • 週の開始曜日は、月曜日
  • その年の第1週は、その年の最初の木曜日を含む週です

2020年の年末・2021年の年始のカレンダーの一部は、次のような感じです。
2021年の1月1日・2日・3日は、2021年ですが「前年である2020年の第53週」に属していることに注目してください。

年と週
2020年 第53週 12/28 12/29 12/30 12/31 1/1 1/2 1/3
2021年 第1週 1/4 1/5 1/6 1/7 1/8 1/9 1/10

2014年の年末・2015年の年始のカレンダーの一部は、次のような感じです。
2014年の12月29日・30日・31日は、2014年ですが「翌年である2015年の第1週」に属していることに注目してください。

年と週
2014年 第52週 12/22 12/23 12/24 12/25 12/26 12/27 12/28
2015年 第1週 12/29 12/30 12/31 1/1 1/2 1/3 1/4

こんな感じで「その年の第何週」という概念、週番号があります。

ISOWeekクラスを使って週番号や年を求める

.NETのISOWeekクラスは、DateTime型に対してISO 8601の週番号を求めるGetWeekOfYearメソッドなどが定義されているクラスです。次にISOWeekクラスを使って、「〇〇年第XX週」のように表示するためのコードを示します。

DateTime date = DateTime.Parse("2021-01-01");

// 「2020年 第53週」と出力される
// 週番号を求めるには、GetWeekOfYearメソッドを使う
// その週の属する年を求めるときは、ISOWeek.GetYearメソッドを使うことに注意
Console.WriteLine(date.ToString($"{ISOWeek.GetYear(date)}年 第{ISOWeek.GetWeekOfYear(date)}週"));

DateTime型に対してISO 8601の週を求めて、「〇〇年第XX週」と表示する時は、「年」にも注意してください。Yearプロパティーを使って表示すると不具合を生んでしまいます。ISOWeekクラスのGetYearメソッドを使いましょう。

先に示した通り2021年1月1日は、2021年でありながら、前年である2020年の第53週に属しています。そのため、Yearプロパティーを使った次のようなコードでは、期待した「2020年 第53週」という出力をしてくれず、「2021年 第53週」と出力してしまいます。

DateTime date = DateTime.Parse("2021-01-01");

// 次のコードは間違い
// 「2021年 第53週」と出力されてしまう
// 2021年1月1日は、2020年の第53週なので間違い
Console.WriteLine(date.ToString($"{date.Year}年 第{ISOWeek.GetWeekOfYear(date)}週"));

ISOWeekクラスにはこれ以外にも、週関連の便利なメソッドが定義されています。

.NET 10で、DateOnly関連のオーバーロード・メソッドが加わりそう

※ 本節は、.NET 10 Preview 1の情報に基づいています。.NET 10の正式リリース前に変わる可能性がある点に注意してください。

.NET 10で、ISOWeekクラスに、DateOnly構造体を引数に取るオーバーロードとメソッドが加わる予定です。

DateOnly構造体は、.NET 6で追加されました。ISOWeekクラスは、.NET Core 3.0で追加されたクラスであり、登場時点でDateOnly構造体はまだなかったため、.NET 10での対応になったようです。

前節で紹介した

の引数としてDateTimeではなく、DateOnlyを引数に取るオーバーロードが追加される予定です。(確かにこのメソッド、意味的には時刻を司るDateTimeじゃなくて、日付を司るDateOnlyを引数に取る方が適切な気がしますね。)

DateOnly date = DateOnly.Parse("2021-01-01");
// 2021年 第53週
Console.WriteLine(date.ToString($"{ISOWeek.GetYear(date)}年 第{ISOWeek.GetWeekOfYear(date)}週"));

ISOWeekには、年・週番号・曜日を引数に取り、DateTime型を返す「ISOWeek.ToDateTime」メソッドがあります。

これとよく似たDateOnlyを返すメソッド「ISOWeek.ToDateOnly」が追加予定です。

DateTime dateTime = ISOWeek.ToDateTime(year: 2020,  week: 53, dayOfWeek: DayOfWeek.Friday);
// 2021/01/01 0:00:00
Console.WriteLine(dateTime);

DateOnly dateOnly = ISOWeek.ToDateOnly(year: 2020,  week: 53, dayOfWeek: DayOfWeek.Friday);
// 2021/01/01 0:00:00
Console.WriteLine(dateOnly);

週番号に対応した書式指定子はない

.NET 9において、週番号に対応した書式指定子はなさそうです。

.NET 10 Preview 1でも、コード見る限りはぱっと見なさそう。

(書式指定子って、後から足せるんだろうか?足したら破壊的な変更になるから、難しい?)

まとめ

  • .NETで、ISO 8601の週番号を扱いたい場合、ISOWeekクラスを使えばOK
  • ISOWeekクラスには、.NET 10で、DateOnlyのメソッド・オーバーロードが追加予定
  • .NET 9において、週番号に対応した書式指定子はない。.NET 10 preview 1段階でもなさそう
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?