CodeGym /コース /C# SELF /日付と時間のフォーマットとパース

日付と時間のフォーマットとパース

C# SELF
レベル 15 , レッスン 3
使用可能

1. 日付のフォーマット

2025-06-19T17:30:00みたいな出力がカッコいいと思っても、おばあちゃんや経理さんに見せたら「もっとシンプルなのがいい」って言われるかも。たとえば19.06.2025 17:30みたいなやつね。英語圏の同僚は06/19/2025 5:30 PMを期待してるし、DevOpsやマシンは2025-06-19T17:30:00Zが好き。だから、プログラムのメモリ上のDateTimeは、画面上で何十通りものフォーマットで表示できるんだ。

逆のパターンもよくあるよ。ユーザーが入力欄に日付を入れる("19.06.2025"とか)とき、それをC#のオブジェクトにちゃんと変換して、日と月を間違えないようにしないとね。自動化や連携、レポート作成でも、テキストの日付を正しく解釈するのが大事だよ。

基本のフォーマット

C#では、日付や時間のオブジェクト(DateTimeDateOnlyTimeOnlyDateTimeOffset)を.ToString()メソッドで文字列に変換できるよ:


DateTime now = DateTime.Now;
Console.WriteLine(now.ToString()); // 出力: 19.06.2025 17:30:25
日付と時間の基本フォーマット

.ToString()をパラメータなしで呼ぶと、システムの現在のカルチャーに合わせたフォーマットになるよ(たとえばドイツ語Windowsなら一つのフォーマット、アメリカ英語なら別のフォーマット)。

標準フォーマット文字列

日付や時間の出力フォーマットを、いわゆる標準フォーマット文字列で明示的に指定できるよ:

フォーマット 説明 出力例
"d"
短い日付 19.06.2025
"D"
フル日付 2025年6月19日
"f"
フル日付+短い時間 2025年6月19日 17:30
"F"
フル日付+フル時間 2025年6月19日 17:30:25
"g"
短い日付と時間 19.06.2025 17:30
"G"
短い日付+フル時間 19.06.2025 17:30:25
"t"
短い時間 17:30
"T"
フル時間 17:30:25
"M"/"m"
月と日 6月19日
"Y"/"y"
年と月 2025年6月
"O"/"o"
ISO 8601(ラウンドトリップ) 2025-06-19T17:30:25.0000000

Console.WriteLine(now.ToString("d")); // 19.06.2025
Console.WriteLine(now.ToString("F")); // 2025年6月19日 17:30:25
Console.WriteLine(now.ToString("O")); // 2025-06-19T17:30:25.0000000

カスタム(ユーザー定義)テンプレート

もっと細かいフォーマットが必要なら、自分でテンプレートを作れるよ:

記号 意味
yyyy 年(4桁)
yy 年(2桁)
MM 月(2桁)
MMMM 月の名前
dd 日(2桁)
d 日(1~2桁)
HH 時(24時間)
mm
ss
tt AM/PM

Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm")); // 2025-06-19 17:30
Console.WriteLine(now.ToString("dd.MM.yyyy"));       // 19.06.2025
Console.WriteLine(now.ToString("dddd, MMMM d"));     // 水曜日, 6月 19

カルチャーごとのフォーマットの違い

他の国や言語っぽいフォーマットにしたいなら、ToString(string, IFormatProvider)のオーバーロードを使おう:


var enUS = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(now.ToString("D", enUS)); // June 19, 2025
  • "MM/dd/yyyy"みたいにテンプレートをガチ指定すれば、カルチャーに関係なく"06/19/2025"になるよ。
  • でも"d""D"だけだと、カルチャーによってフォーマットが変わるから注意!

フォーマット作業の注意ポイント

日付フォーマットを扱うときは、標準フォーマットとカスタムフォーマットの違いをちゃんと理解しよう。標準フォーマット("d""F""G"など)はシステムのカルチャーに自動で合わせてくれるからUIには便利だけど、システム間のデータ交換ではトラブルの元になることも。カスタムフォーマットなら出力を完全にコントロールできるけど、細かい設定が必要だよ。

特に"O"(または"o")フォーマットは要チェック。これは「ラウンドトリップ」フォーマットで、文字列に変換してまたオブジェクトに戻しても、値が絶対に変わらないって保証してくれる。データのシリアライズやネットワーク越しのやりとりで超重要だよ。

2. 日付と時間のパース:文字列からオブジェクトへ

一番シンプルなパース:DateTime.Parse

DateTime.Parseは、システムのカルチャーを考慮して日付文字列を解釈してくれるメソッドだよ。


string input = "19.06.2025";
DateTime parsed = DateTime.Parse(input);
Console.WriteLine(parsed); // 19.06.2025 00:00:00

もし文字列が変だったら、プログラムは例外で落ちるから(誰でもやらかす!)注意してね。

カルチャーの指定


string input = "06/19/2025";
var enUS = new System.Globalization.CultureInfo("en-US");
DateTime dt = DateTime.Parse(input, enUS);
Console.WriteLine(dt); // 19.06.2025 00:00:00

安全なパース:TryParse


string input = "まちがった日付";
bool ok = DateTime.TryParse(input, out DateTime safeDate);
if (!ok)
    Console.WriteLine("エラー: 日付の認識に失敗したよ!");

フォーマットをガチ指定:ParseExactとTryParseExact


var culture = System.Globalization.CultureInfo.InvariantCulture;
string dateStr = "2025-06-19";

DateTime d = DateTime.ParseExact(dateStr, "yyyy-MM-dd", culture);
Console.WriteLine(d); // 19.06.2025 00:00:00

bool parsedOk = DateTime.TryParseExact(
    "19.06.2025",
    "dd.MM.yyyy",
    System.Globalization.CultureInfo.InvariantCulture,
    System.Globalization.DateTimeStyles.None,
    out DateTime myDate);

よく使うフォーマットの表

文字列 フォーマット 最終オブジェクト
"2025-06-19" "yyyy-MM-dd" 2025年6月19日
"19.06.2025" "dd.MM.yyyy" 2025年6月19日
"06/19/2025" "MM/dd/yyyy" 2025年6月19日
"2025-06-19T14:15:16" "s" 2025年6月19日 14:15:16

DateTimeStylesの使い方

パース時にDateTimeStylesパラメータで動作を細かく制御できるよ。このenumで、パーサーが入力データをどう解釈するか決められる。たとえばDateTimeStyles.AssumeUniversalは、オフセットが明示されてない場合にUTCとして扱う。DateTimeStyles.AllowWhiteSpacesは、余計なスペースを無視してくれる。外部データを扱うとき、フォーマットが予測できない場合に便利だよ。

3. DateOnlyTimeOnlyのフォーマットとパース

最近はDateOnlyTimeOnlyみたいな新しい型が、余計な情報なしで日付や時間を保存するのによく使われてるよ。

フォーマット


DateOnly birthday = new DateOnly(2000, 6, 19);
Console.WriteLine(birthday.ToString("dd MMMM yyyy")); // 2000年6月19日

パース


var d = DateOnly.ParseExact("19.06.2000", "dd.MM.yyyy");
Console.WriteLine(d.Day); // 19

TimeOnly用のメソッドも同じ感じ(テンプレートは時・分・秒だけだけどね):

TimeOnly t = TimeOnly.ParseExact("23:59", "HH:mm");
Console.WriteLine(t.Hour); // 23

DateOnlyとTimeOnlyのメリット

DateOnlyTimeOnlyDateTimeの代わりに使うと、いくつか大きなメリットがあるよ。まず、意味がハッキリする。たとえば誕生日みたいに時間がいらない場合、DateOnlyを使えば意図が明確。次に、DateTimeでありがちなタイムゾーンの問題を避けられる。そして、これらの型はメモリやDBで場所も少なくて済むんだ。

タイムゾーンを考慮したフォーマットとパース

オフセット付きで時間を保存したいなら、DateTimeOffsetを使おう。これは国際化や分散システムで特に重要。フォーマットやパースのやり方は同じだけど、オフセットも管理できるよ:


DateTimeOffset meeting = new DateTimeOffset(2025, 6, 19, 17, 30, 0, TimeSpan.FromHours(3));
Console.WriteLine(meeting.ToString("o")); // 2025-06-19T17:30:00.0000000+03:00

string input = "2025-06-19T17:30:00+03:00";
var parsedOffset = DateTimeOffset.Parse(input);
Console.WriteLine(parsedOffset.Offset); // 03:00:00

4. 実践的な注意点とよくあるミス

ありがちな落とし穴は、国際フォーマットのパースで「日」と「月」を間違えること。たとえば"01/02/2025"はアメリカだと1月2日じゃなくて2月1日、ヨーロッパだと1月2日(びっくり!)。

それから、カルチャーの影響を忘れがち。たとえばアプリがドイツのサーバーで動いてて、ユーザーは色んな国からアクセスしてる場合、DBの日付フォーマットがサーバーごとに違って解釈されることもあるよ。

よくあるミスは、ログやデータ交換ファイルで.ToString()をカルチャーやフォーマット指定なしで使っちゃうこと。OSを変えたり、Windowsのユーザーを変えたりすると、結果が変わっちゃうかも。

日付操作のおすすめ

  • 内部保存やデータ交換には、必ずインバリアントカルチャー(CultureInfo.InvariantCulture)や明示的なフォーマットを使おう。
  • UIにはユーザーのカルチャーを使うか、好みのフォーマットを選ばせてあげよう。
  • APIやDBでは、国際標準のISO 8601フォーマットを優先しよう。
  • 入力データは必ずバリデーションしよう。日付の存在や範囲、値の妥当性をチェック!

いろんなデータソースとのやりとり

外部システムと連携するときは、いろんなフォーマットの日付を扱うことが多いよ。Unix timestamp(1970年1月1日からの秒数)で送ってくるシステムもあれば、各国のフォーマットの文字列で送ってくる場合も。事前にデータ交換フォーマットを決めて、パースの正しさを必ずチェックしよう。

それから、あいまいなフォーマットもあるから注意。たとえば"12/13/2025"は確実に2025年12月13日だけど、"12/11/2025"はカルチャーによって11月12日か12月11日になる。こういう場合は、あいまいじゃないフォーマットを使うか、パース時にカルチャーを明示しよう。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION