Menu

C#のDateTimeの書式:標準とカスタムの書式文字列、カルチャ、ISO 8601

C#でDateTimeを文字列に書式設定する方法を解説します。標準の書式文字列(d、D、o、s、u、t)、yyyy-MM-dd HH:mm:ssのようなカスタムパターン、指定子の一覧表、カルチャによる出力の変化、"o"によるISO 8601のラウンドトリップ、そしてmmとMM、hhとHHの取り違えを扱います。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

DateTime.ToString(format) は日付をテキストに変換します。書式は、標準の書式文字列(d や o のような1文字で、正確なパターンはカルチャから決まります)か、yyyy、MM、HH などの指定子で組み立てるカスタムパターンのどちらかです。同じ文字列が補間 $"{date:yyyy-MM-dd}" でも string.Format でも使えます。

出力:

2026-10-09
2026-10-09 18:30:07
09/10/2026
Oct 9, 2026
Friday, October 9
6:30 PM
18:30:07.045
Shipped 2026-10-09 at 18:30

このページの例では、どのマシンでも出力が同じになるように CultureInfo.InvariantCulture を渡しています。渡さないと ToString は現在のカルチャを使い、月の名前、区切り文字、さらには暦まで変わることがあります。

カスタムの書式指定子

カスタムの書式は、特定の文字が日付の各部分を表すパターンです。大文字と小文字を区別します。M は月で m は分、H は24時間表記の時で h は12時間表記の時です。

指定子意味2026-10-09 18:30:07.045の例
yyyy年、4桁2026
yy年、2桁26
MMMM月の完全な名前October
MMM月の短縮名Oct
MM月、2桁10
M月、1桁または2桁10
dddd曜日の完全な名前Friday
ddd曜日の短縮名Fri
dd日、2桁09
d日、1桁または2桁(パターンの中で)9
HH時、00から2318
H時、0から2318
hh時、01から1206
h時、1から126
mm分、2桁30
ss秒、2桁07
fffミリ秒045
fffffffティック(小数部分7桁)0450000
ttAM/PMの記号PM
zzzUTCからのオフセット(DateTimeOffset またはローカル時刻)+02:00
Kゾーンの情報:Z、オフセット、またはなしZ(UTCの値の場合)
/カルチャの日付の区切り文字/ または . または -
:カルチャの時刻の区切り文字:
'text' または \cそのままのテキストまたは文字'at'

それ以外の文字はそのままコピーされます。指定子でない英字も含まれるので、"YYYY-DD" は何も言わずに YYYY-DD と表示されます。.NETには大文字の Y や D の指定子はありません。

1文字だけの書式は、カスタムではなく標準の書式として読まれます。ToString("d") は日の数値ではなく短い日付のパターンです。日だけを得るには、ToString("%d") と書くか、Day プロパティを使います。

出力:

10/09/2026
9
20261009_183007
Week of Oct 9
18h30
2026-10-09T18:30:07
YYYY-DD

標準の書式文字列

標準の書式は、実際のパターンがカルチャによって定義される1文字の書式です。各カルチャが独自の慣例を自動的に得られるので、ユーザーに見せるテキストに適しています。

出力:

d  10/09/2026
D  Friday, 09 October 2026
f  Friday, 09 October 2026 18:30
g  10/09/2026 18:30
G  10/09/2026 18:30:07
M  October 09
Y  2026 October
t  18:30
T  18:30:07
o  2026-10-09T18:30:07.0000000Z
s  2026-10-09T18:30:07
u  2026-10-09 18:30:07Z
r  Fri, 09 Oct 2026 18:30:07 GMT
en-US d: 10/9/2026, D: Friday, October 9, 2026
コード名前カルチャに依存するか
d / D短い / 長い日付する
t / T短い / 長い時刻する
f / F長い日付と短い / 長い時刻する
g / G短い日付と短い / 長い時刻する
M月と日する
Y年と月する
oラウンドトリップのISO 8601、小数部分7桁、ゾーンしない
s並べ替え可能なISO 8601、小数部分なし、ゾーンなししない
u世界共通の並べ替え可能な形式、末尾が Zしない
rRFC 1123、HTTPヘッダー用しない

o、s、u、r はどのカルチャでも同じテキストを生成するので、ログ、ファイル名、データの交換に安全に使えます。DateTime に対する u と r は値をUTCに変換しないことに注意してください。値をそのまま表示してUTCというラベルを付けるだけなので、値がローカル時刻なら先に ToUniversalTime() を呼びます(または DateTime.UtcNow を使います)。(DateTimeOffset に対しては変換されます。)

カルチャによって出力が変わる

標準の書式、月と曜日の名前、/ と : の区切り文字は、すべてカルチャから来ます。ToString の2番目の引数としてカルチャを渡します。

出力:

en-US  10/9/2026
en-GB  09/10/2026
de-DE  09.10.2026
fr-FR  09/10/2026
ja-JP  2026/10/09
Freitag, 9. Oktober 2026
vendredi 9 octobre 2026
09.10.2026
09/10/2026

カルチャのデータは固定されていません。LinuxとmacOSの.NETはシステムにインストールされたICUライブラリからデータを読み、.NET 5以降はWindows 10以降の.NETも同じです(.NET FrameworkはWindows自身のNLSのデータを使います)。そのため、パターンはバージョンやプラットフォームによってわずかに変わることがあります。たとえば最近のICUのリリースでは、米国の短い時刻の書式で「PM」の前に普通の空白ではなく細い改行なしの空白を置き、スペイン語の短い日付で先頭のゼロを付けないものもあります。表示用に書式設定したテキストを決して解析すべきでない理由が、もう1つ増えます。

ここから2つのルールが導かれます。人が読むテキストは、その人のカルチャで書式設定し(サーバーでは、サーバーのものではなくリクエストのカルチャで)、標準の書式を優先します。そうすれば、ドイツの読者は 09.10.2026 を、米国の読者は 10/9/2026 を見ます。プログラムが読むテキストには、CultureInfo.InvariantCulture と、yyyy-MM-dd や o のようなあいまいさのないパターンを使います。現在のカルチャで書き出した日付を別のマシンで解析するのは、日と月が入れ替わる典型的な原因です。

ISO 8601と"o"によるラウンドトリップ

ラウンドトリップの書式 "o" はすべてのティックとゾーンの情報を書き出すので、そのテキストを解析すると、Kind も含めてまったく同じ DateTime が得られます。

出力:

2026-10-09T18:30:07.0450000Z
2026-10-09T18:30:07.0450000
2026-10-09T20:30:07.0000000+02:00
True
Utc
2026-10-09T18:30:07Z
2026-10-09 20:30 +02:00

接尾辞の Z はUTCを表し、Kind が Unspecified の DateTime には接尾辞が付かず、ローカル時刻や DateTimeOffset にはオフセット(+02:00)が付きます。Kind が保たれるように、DateTimeStyles.RoundtripKind を指定して解析します。JSONのシリアライザー、データベース、JavaScriptの Date はすべてこの形式を読めます。

TimeSpanの書式設定

TimeSpan には、より小さな独自のカスタム指定子の集まりがあります:d(日)、hh、mm、ss、fff。DateTime と違い、: や . を含むすべてのリテラルの文字を、バックスラッシュでエスケープするか引用符で囲む必要があります。

出力:

1.03:25:09.1200000
1.03:25:09.1200000
03:25:09
1.03:25
25:09.120
27:25

TimeSpan の書式の hh は時間の成分(0から23)なので、27時間の期間は 03 と表示されます。1日を超える合計には、最後の行のように TotalHours から計算します。バックスラッシュのない elapsed.ToString("hh:mm") は FormatException を投げます。

よくある間違い

  • 月に mm を使う。 "yyyy-mm-dd" は真ん中に分を表示します:2026-30-09。月は MM です。
  • tt なしの hh。 "hh:mm" はAMもPMもない12時間表記なので、06:30があいまいになります。24時間表記には HH を使います。
  • YYYY と DD。 .NETでは指定子ではなく、そのまま表示されます。yyyy と dd を使います。
  • データ用のパターンの /。 カルチャの日付の区切り文字です。引用符で囲むか、インバリアントカルチャを使います。
  • ログやファイルでの既定の ToString()。 書式がマシンに依存します。書式とカルチャを渡します。
  • UTCとラベルを付けたローカル時刻。 "u"、"r"、手書きの 'Z' は変換しません。先に変換します。
  • 書き出したときとは異なるパターンで解析する。 データ用の書式文字列は1つの定数にまとめ、ToString と ParseExact の両方で使います。

よくある質問

C#でDateTimeをyyyy-MM-ddの形式にするには?

date.ToString("yyyy-MM-dd") で 2026-10-09 が得られます。補間文字列では $"{date:yyyy-MM-dd}" と書きます。24時間表記の時刻には " HH:mm:ss" を加えます。テキストがファイルや別のプログラムのためのものなら、2番目の引数に CultureInfo.InvariantCulture を渡し、暦、月の名前、区切り文字がマシンに依存しないようにします。

C#の日付の書式でmmとMMの違いは何ですか?

MM は月(01から12)で、mm は分(00から59)です。書式は大文字と小文字を区別するので、yyyy-mm-dd は月の位置に分を表示します。1つの値をちらっと見ただけでは見逃しやすいバグです。同様に、HH は24時間表記の時、hh は12時間表記の時です。

C#でDateTimeをISO 8601の形式にするには?

ラウンドトリップの書式 "o" を使います。DateTime.UtcNow.ToString("o") は 2026-10-09T18:30:07.0450000Z のように、小数部分7桁と、UTCなら Z、ローカル時刻ならオフセットを付けて出力します。"s" は小数部分とゾーンのない短い並べ替え可能な形式で、"yyyy-MM-ddTHH:mm:ssZ" はよく使われるカスタムの変形です。

C#の日付の書式でAMとPMを表示するには?

12時間表記には hh か h を、AM/PMの記号には tt を使います:date.ToString("h:mm tt", CultureInfo.GetCultureInfo("en-US")) で 6:30 PM になります。記号はカルチャから取られ、記号を持たないカルチャもあるので、AMとPMが必要ならカルチャを明示的に渡します。

日付の書式でスラッシュの代わりにドットが表示されるのはなぜですか?

書式文字列の中の / はそのままのスラッシュではなくカルチャの日付の区切り文字で、: はカルチャの時刻の区切り文字だからです。ドイツ語のマシンでは dd/MM/yyyy は 09.10.2026 と表示されます。文字を引用符で囲んで強制する(dd'/'MM'/'yyyy)か、CultureInfo.InvariantCulture で書式設定します。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める