はじめに なぜ「ファイル作成日時取得」が業務で重要なのか
業務システムでは、「一番新しいファイルだけ処理したい」「一定期間より古いファイルを削除したい」「いつ受信したファイルなのかをログに残したい」といった場面で、ファイルの作成日時を扱うことがよくあります。
作成日時を見ずに処理すると、「古いファイルを再処理してしまう」「想定より新しいデータを取り込めていない」といった、微妙に厄介な不具合につながります。
C# では、File クラスや FileInfo クラスを使って、ファイルの作成日時を簡単に取得できます。
ここでは、プログラミング初心者向けに、基本の使い方から、業務で使えるユーティリティ化、ローカル時刻と UTC の違い、日付条件での絞り込みまで、かみ砕いて解説していきます。
基本の API File.GetCreationTime と FileInfo.CreationTime
一番シンプルな作成日時取得
まずは、「特定のファイルの作成日時を取得して表示する」という、一番シンプルな例から見てみましょう。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
DateTime created = File.GetCreationTime(path);
Console.WriteLine($"作成日時: {created}");
}
}
C#File.GetCreationTime は、指定したパスのファイルの作成日時を DateTime 型で返します。
ここで返ってくるのは「ローカル時刻(PC のタイムゾーンを反映した時刻)」です。
日本の PC であれば、日本時間として解釈できる値になります。
この時点で押さえておきたいのは、「作成日時は DateTime で扱う」「ローカル時刻と UTC の違いがある」という二点です。
この「時刻の種類」の話は、後で少し深掘りします。
FileInfo を使った書き方
同じことは FileInfo クラスでも書けます。
ファイルサイズや更新日時など、他の情報も一緒に扱いたいときは、FileInfo を使うとコードがまとまりやすくなります。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
FileInfo info = new FileInfo(path);
DateTime created = info.CreationTime;
Console.WriteLine($"作成日時: {created}");
}
}
C#FileInfo.CreationTime も、ローカル時刻の DateTime を返します。
「サイズも欲しい」「更新日時も欲しい」といった場合は、FileInfo 一択で考えてしまって構いません。
ローカル時刻と UTC 時刻 CreationTimeUtc の意味
CreationTime と CreationTimeUtc の違い
FileInfo には、CreationTime のほかに CreationTimeUtc というプロパティもあります。
名前の通り、こちらは「UTC(協定世界時)」での作成日時を返します。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
FileInfo info = new FileInfo(path);
DateTime localTime = info.CreationTime;
DateTime utcTime = info.CreationTimeUtc;
Console.WriteLine($"ローカル時刻: {localTime}");
Console.WriteLine($"UTC 時刻 : {utcTime}");
}
}
C#日本時間は UTC より 9 時間進んでいるので、例えばローカルが「2025-01-23 18:00」であれば、UTC は「2025-01-23 09:00」のようになります。
国内だけで完結するシステムならローカル時刻だけでも困らないことが多いですが、ログの統一や他システムとの連携を考えると、「内部では UTC で持つ」という設計もよく使われます。
業務でどう使い分けるか
初心者向けのざっくりした指針としては、次のように考えると分かりやすいです。
画面表示やログ出力など、「人間が直接見るもの」はローカル時刻(CreationTime)で扱う。
システム間連携や DB 保存など、「後でタイムゾーンを変換する可能性があるもの」は UTC(CreationTimeUtc)で扱う。
たとえば、「DB には UTC で保存し、画面に出すときだけ日本時間に変換する」といったパターンです。
最初から完璧に設計しようとしなくてよいですが、「ローカルと UTC の二種類がある」ということだけは、頭の片隅に置いておくと後で楽になります。
実務で使えるユーティリティ 単体ファイルの作成日時取得
存在チェック込みのユーティリティメソッド
毎回 File.Exists と File.GetCreationTime を書くのは面倒なので、「存在チェック込みの作成日時取得」ユーティリティを用意しておくと便利です。
using System;
using System.IO;
public static class FileCreatedTimeUtil
{
public static DateTime GetCreatedTime(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"ファイルが見つかりません: {filePath}", filePath);
}
return File.GetCreationTime(filePath);
}
public static DateTime GetCreatedTimeUtc(string filePath)
{
if (!File.Exists(filePath))
{
throw new FileNotFoundException($"ファイルが見つかりません: {filePath}", filePath);
}
return File.GetCreationTimeUtc(filePath);
}
}
C#使い方の例は次の通りです。
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
try
{
DateTime created = FileCreatedTimeUtil.GetCreatedTime(path);
Console.WriteLine($"作成日時(ローカル): {created}");
DateTime createdUtc = FileCreatedTimeUtil.GetCreatedTimeUtc(path);
Console.WriteLine($"作成日時(UTC) : {createdUtc}");
}
catch (FileNotFoundException ex)
{
Console.WriteLine("エラー: " + ex.Message);
}
}
}
C#ここでのポイントは、「存在しない場合は 0 や既定値ではなく、例外として扱う」設計にしていることです。
業務的に「ファイルがないのは異常」であることが多いので、その場合は例外で止めたほうがバグに気づきやすくなります。
「存在しないなら null」を返すバージョン
一方で、「存在しなければ null として扱いたい」というケースもあります。
その場合は、DateTime?(null 許容)で返すメソッドを用意します。
public static class FileCreatedTimeUtil
{
public static DateTime? TryGetCreatedTime(string filePath)
{
if (!File.Exists(filePath))
{
return null;
}
return File.GetCreationTime(filePath);
}
}
C#呼び出し側では、null かどうかで存在有無を判定できます。
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
DateTime? created = FileCreatedTimeUtil.TryGetCreatedTime(path);
if (created == null)
{
Console.WriteLine("ファイルが存在しません。");
}
else
{
Console.WriteLine($"作成日時: {created.Value}");
}
}
}
C#「例外で止めるか」「null で返すか」をメソッドごとに分けておくと、呼び出し側の意図が明確になります。
作成日時を使った業務ロジックの例
一番新しいファイルだけ処理する
よくある要件として、「フォルダ内で一番新しいファイルだけを処理したい」というものがあります。
たとえば、C:\import に毎日ファイルが届き、その中で最新のものだけを取り込むケースです。
using System;
using System.IO;
public static class FileSearchUtil
{
public static string? GetLatestFile(string directoryPath, string searchPattern = "*.*")
{
if (!Directory.Exists(directoryPath))
{
throw new DirectoryNotFoundException($"ディレクトリが見つかりません: {directoryPath}");
}
string[] files = Directory.GetFiles(directoryPath, searchPattern);
if (files.Length == 0)
{
return null;
}
string latestFile = files[0];
DateTime latestTime = File.GetCreationTime(latestFile);
foreach (string file in files)
{
DateTime created = File.GetCreationTime(file);
if (created > latestTime)
{
latestTime = created;
latestFile = file;
}
}
return latestFile;
}
}
C#使い方の例は次の通りです。
class Program
{
static void Main()
{
string dir = @"C:\import";
string? latest = FileSearchUtil.GetLatestFile(dir, "*.csv");
if (latest == null)
{
Console.WriteLine("対象ファイルがありません。");
}
else
{
Console.WriteLine($"最新ファイル: {latest}");
}
}
}
C#ここでの重要ポイントは、「作成日時を比較して最大のものを選んでいる」ことです。
更新日時(LastWriteTime)を使うパターンもありますが、「いつ作られたか」を基準にしたい場合は作成日時を使います。
一定日数より古いファイルを削除する
もう一つよくあるのが、「30 日より古いログファイルを削除する」といった、期限付きのクリーンアップ処理です。
この場合も、作成日時を使って判定できます。
using System;
using System.IO;
public static class LogCleanupUtil
{
public static int DeleteOldFiles(string directoryPath, int days)
{
if (!Directory.Exists(directoryPath))
{
throw new DirectoryNotFoundException($"ディレクトリが見つかりません: {directoryPath}");
}
DateTime threshold = DateTime.Now.AddDays(-days);
int deletedCount = 0;
foreach (string filePath in Directory.GetFiles(directoryPath))
{
DateTime created = File.GetCreationTime(filePath);
if (created < threshold)
{
File.Delete(filePath);
deletedCount++;
}
}
return deletedCount;
}
}
C#使い方の例は次の通りです。
class Program
{
static void Main()
{
string dir = @"C:\logs\app";
int deleted = LogCleanupUtil.DeleteOldFiles(dir, days: 30);
Console.WriteLine($"削除したファイル数: {deleted}");
}
}
C#ここでのポイントは、「基準日時(threshold)を先に計算しておき、それより古いかどうかで判定している」ことです。DateTime.Now.AddDays(-30) のように、「今から 30 日前」を求める書き方は、業務ロジックで頻出するので覚えておくと便利です。
日付・時刻を扱うときの注意点
作成日時は「絶対に正しい」とは限らない
実務的な注意点として、「作成日時は必ずしも真実を表しているとは限らない」という点があります。
ファイルを別の場所にコピーしたとき、コピー先の作成日時は「コピーした時刻」になることが多いです。
また、システムによっては、作成日時が更新されたり、タイムゾーンの設定変更で見え方が変わったりすることもあります。
そのため、「作成日時だけを唯一の真実として扱う」のではなく、「更新日時やファイル名の日付、DB に記録した受信日時」など、他の情報と組み合わせて判断するのが安全です。
とはいえ、「だいたいの新旧判定」や「一定期間より古いものの削除」など、多くの場面では作成日時で十分役に立ちます。
ローカル時刻と DateTimeKind
File.GetCreationTime や FileInfo.CreationTime が返す DateTime は、Kind プロパティが DateTimeKind.Local になっています。CreationTimeUtc のほうは DateTimeKind.Utc です。
国内だけで完結するシステムなら、あまり意識しなくても困らないことが多いですが、他システムとの連携やクラウド環境などでは、「どの時刻がどのタイムゾーンなのか」を意識しておくとトラブルを減らせます。
最初のうちは、「ローカル用」「UTC 用」の二種類のメソッドを用意しておき、用途に応じて使い分ける、くらいの感覚で十分です。
例外とエラー処理を意識した作成日時取得
どんな例外が起こり得るか
ファイル作成日時の取得では、次のような理由で例外が発生する可能性があります。
ファイルが存在しない、権限がなくてアクセスできない、パスが不正または長すぎる、ファイルシステムに問題がある、などです。
呼び出し側での例外処理の例を見てみます。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = @"C:\data\report.csv";
try
{
DateTime created = FileCreatedTimeUtil.GetCreatedTime(path);
Console.WriteLine($"作成日時: {created}");
}
catch (FileNotFoundException ex)
{
Console.WriteLine("ファイルが見つかりません: " + ex.Message);
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("権限エラーが発生しました: " + ex.Message);
}
catch (IOException ex)
{
Console.WriteLine("入出力エラーが発生しました: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("想定外のエラーが発生しました: " + ex.Message);
}
}
}
C#実務では、これらのメッセージをログに残しておくことで、「どのファイルの作成日時取得に、どんな理由で失敗したか」を後から追跡できます。
まとめ 実務で使えるファイル作成日時取得ユーティリティの考え方
ファイル作成日時の取得は、一見シンプルですが、「最新ファイルの判定」「古いファイルの削除」「受信時刻の記録」など、業務システムの運用を支える重要な要素です。
だからこそ、「ただ CreationTime を読む」だけで終わらせず、ユーティリティとして整理しておく価値があります。
File.GetCreationTime や FileInfo.CreationTime を使って、作成日時を DateTime として正しく扱うこと。
存在チェック込みのユーティリティ(例外を投げる版と、null を返す版)を用意し、用途に応じて使い分けること。
ローカル時刻と UTC(CreationTimeUtc)の違いを理解し、「人が見る用」と「システム内部用」で使い分けること。
作成日時を使って「最新ファイルの選択」や「一定日数より古いファイルの削除」といった業務ロジックを組み立てること。
作成日時が必ずしも絶対ではないことを意識しつつ、他の情報と組み合わせて運用設計を考えること。
ここまで押さえておけば、「いつのファイルを処理しているのか分からない」「古いファイルが溜まり続けてディスクが圧迫される」といった、現場でよくある悩みをかなり減らせます。
