DateTime/DateTimeOffsetでは、標準の書式指定子O/o(書式指定子 §.O, o (round-trip date/time))またはs(書式指定子 §.s (sortable date/time))によってISO 8601の拡張形式で文字列化することができます。 ただし、いずれの書式でも日付部分には(グレゴリオ暦での)年月日が用いられます。
ISOWeekクラスには日付をISO週暦での年・週・曜日を用いた形式で文字列化するメソッドは用意されておらず、また(少なくとも.NET 5時点では)標準の書式指定子にもそういった書式は用意されていません。 そのため、必要な場合はISOWeekクラスのメソッドを組み合わせて独自に実装する必要があります。
ISO週暦での日付をISO 8601拡張形式で文字列化する
using System;
using System.Globalization;
class Sample {
static int GetISOWeekdayNumber(DateTime date) => date.DayOfWeek == DayOfWeek.Sunday ? 7 : (int)date.DayOfWeek;
// DateTimeで与えられる日付をISO 8601拡張形式(年・週・曜日)で文字列化する
static string ToISO8601WeekDateFormatString(DateTime date)
=> string.Format(
"{0:D4}-W{1:D2}-{2:D2}",
ISOWeek.GetYear(date), // DateTimeに対応するISO週年を取得
ISOWeek.GetWeekOfYear(date), // DateTimeに対応するISO週番号を取得
GetISOWeekdayNumber(date) // DateTimeに対応するISO曜日番号を取得
);
static void Main()
{
var dates = new[] {
new DateTime(2019, 12, 29),
new DateTime(2019, 12, 30),
new DateTime(2020, 1, 1),
new DateTime(2020, 6, 30),
new DateTime(2020, 12, 31),
new DateTime(2021, 1, 3),
new DateTime(2021, 12, 31),
};
foreach (var d in dates) {
// ISO 8601拡張形式の年・月・日(秒の端数部を除く)および年・週・曜日の書式で文字列化する
Console.WriteLine(
"{0} => {1}",
d.ToString("s"),
ToISO8601WeekDateFormatString(d)
);
}
}
}
実行結果
2019-12-29T00:00:00 => 2019-W52-07 2019-12-30T00:00:00 => 2020-W01-01 2020-01-01T00:00:00 => 2020-W01-03 2020-06-30T00:00:00 => 2020-W27-02 2020-12-31T00:00:00 => 2020-W53-04 2021-01-03T00:00:00 => 2020-W53-07 2021-12-31T00:00:00 => 2021-W52-05