C# Tips | 日付・時間処理:ファイル名用日時

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

はじめに 「ファイル名用日時」は“あとから探しやすく、壊れにくい名前のコア”

バックアップファイル、エクスポートCSV、ログのローテーションファイル。
こういう「時刻付きファイル名」を付けるとき、
なんとなく DateTime.Now.ToString() をくっつけると、だいたい痛い目を見ます。

理由はシンプルで、
ファイル名には「使えない文字」があり、
ロケールによって /: が入ったり、
ソートしたときに時系列順にならなかったりするからです。

だからこそ、「ファイル名用日時」は
ルールを決めてユーティリティ化しておく価値が高いテーマです。


基本方針:ファイル名に安全で、ソートすると時系列になる形にする

使ってはいけない文字を避ける

Windows などのファイルシステムでは、
/ \ : * ? " < > | などはファイル名に使えません。
DateTime.ToString() のデフォルトは、平気で /: を含みます。

なので、ファイル名用の日時は
「数字と一部の記号だけ」で構成するのが安全です。

よく使われるのは、こんな形です。

  • yyyyMMdd_HHmmss
  • yyyyMMdd_HHmmssfff(ミリ秒付き)

例:20260218_20453020260218_204530123

この形なら、
ファイル名として安全で、
文字列としてソートしたときにそのまま時系列順になります。


実装:ファイル名用日時文字列を返すユーティリティ

秒単位のファイル名用日時

まずは秒単位のシンプルなユーティリティです。

using System;
using System.Globalization;

public static class FileNameTimeUtil
{
    public static string GetFileNameTimestamp()
    {
        DateTime now = DateTime.Now;

        return now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);
    }
}
C#

使い方の例です。

string ts = FileNameTimeUtil.GetFileNameTimestamp();
string fileName = $"backup_{ts}.zip";

Console.WriteLine(fileName);
// 例: backup_20260218_204530.zip
C#

ここでの重要ポイントは、

  • フォーマットを "yyyyMMdd_HHmmss" に固定していること
  • CultureInfo.InvariantCulture を指定して、環境によって変わらないようにしていること

です。

ミリ秒付き(衝突を減らしたい場合)

同じ秒の間に複数ファイルを作る可能性があるなら、
ミリ秒まで含めてしまうのが手軽です。

public static string GetFileNameTimestampWithMillis()
{
    DateTime now = DateTime.Now;

    return now.ToString("yyyyMMdd_HHmmssfff", CultureInfo.InvariantCulture);
}
C#

例:backup_20260218_204530123.log


UTC を使うかローカルを使うか

「どの時間軸で管理したいか」を決める

ログ用日時と同じく、
ファイル名用日時も「UTC で統一するか」「ローカル時間でいいか」を決める必要があります。

複数サーバー間でファイルを集約する、
タイムゾーンが混在する、
といったシステムなら、UTC にそろえたほうが後々楽です。

public static string GetFileNameTimestampUtc()
{
    DateTime utcNow = DateTime.UtcNow;

    return utcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture);
}
C#

ただし、運用担当者が「日本時間で見たい」など、
ローカル時間のほうが直感的なケースもあります。

その場合は、

  • ファイル名はローカル時間
  • メタデータやログには UTC も別途持つ

のように、用途ごとに使い分ける設計もアリです。


実務でよくあるパターン別の例

バックアップファイル

日次バックアップなどでは、
「日付+時刻+連番」のような形がよく使われます。

string ts = FileNameTimeUtil.GetFileNameTimestamp();
string fileName = $"db_backup_{ts}.bak";
// db_backup_20260218_020000.bak
C#

日次で1ファイルなら日付だけでもよいですが、
手動実行やリトライなどを考えると、時刻まで入れておくほうが安全です。

ローテーションログ

ログファイルをローテーションするときも、
ファイル名に日時を埋め込むのが定番です。

string ts = FileNameTimeUtil.GetFileNameTimestampWithMillis();
string fileName = $"app_{ts}.log";
// app_20260218_204530123.log
C#

ミリ秒まで入れておけば、
同じ秒にローテーションが走っても衝突しにくくなります。


実務での注意点:フォーマットを“1箇所に固定する”

あちこちで ToString("yyyyMMdd_HHmmss") と書かない

プロジェクトのあちこちで、
それぞれが勝手に

DateTime.Now.ToString("yyyyMMdd_HHmmss")
C#

と書き始めると、
そのうち誰かが "yyyy-MM-dd_HH-mm-ss" とか "yyyyMMddHHmmss" とか
微妙に違うフォーマットを使い始めます。

結果として、

  • ファイル名のパターンが揃わない
  • 後処理(バッチ・集計)が書きづらい
  • 正規表現やパースが複雑になる

という“じわじわ効く痛み”が出てきます。

だからこそ、

public static class FileNameTimeUtil
{
    public static string Now() => ...;
    public static string NowWithMillis() => ...;
}
C#

のように、「ファイル名用日時は必ずここを通す」という
ユーティリティを1箇所に決めておくのが大事です。


まとめ 「ファイル名用日時ユーティリティ」は“安全で探しやすい名前の型”

ファイル名用日時は、
単なる飾りではなく、

  • ファイル名として安全であること
  • ソートしたときに時系列になること
  • 環境によって変わらないこと

といった性質を満たす“設計された文字列”です。

押さえておきたいポイントはこうです。

  • フォーマットは "yyyyMMdd_HHmmss"(+fff)のように、数字と安全な記号だけにする
  • CultureInfo.InvariantCulture を使って、ロケール依存をなくす
  • UTC を使うかローカルを使うかは要件次第だが、どちらかに統一する
  • バックアップ・ログ・エクスポートなど、用途ごとに同じルールを使い回す
  • プロジェクト全体で「ファイル名用日時はこのユーティリティを使う」と決めて、一貫性を守る

ここまで決めてしまえば、
「とりあえず今の時刻をくっつける」から卒業して、
“壊れにくくて後から探しやすいファイル名”を、毎回迷わず付けられるようになります。

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