C# DateTimeの使い方完全ガイド|日付取得・文字列変換・比較・フォーマット・時刻計算まで解説

はじめに

C#で日付や時刻を扱うときに最もよく使われる型がDateTimeです。現在日時の取得、日付の比較、文字列への変換、日付計算、ログ出力、CSVやAPIの日付データ処理など、実務でも頻繁に登場します。

一方で、DateTimeは便利な反面、フォーマット指定、タイムゾーン、UTC、日付だけの比較、nullの扱いなどでつまずきやすい型でもあります。特に、DateTime.NowDateTime.UtcNowの違いや、MMmmの書式指定子の違いを理解していないと、意図しない日時が表示・保存されることがあります。

この記事では、C#のDateTimeについて、基本的な使い方から文字列変換、比較、計算、フォーマット、タイムゾーン、実務で使えるサンプルコードまで体系的に解説します。

1. C#のDateTimeとは?日付・時刻を扱う基本

1-1. DateTime構造体の役割とできること

DateTimeは、C#で日付と時刻を表すための構造体です。年月日だけでなく、時分秒、ミリ秒、さらに内部的には100ナノ秒単位の値で日時を扱います。

たとえば、以下のような処理に使えます。

C#
DateTime now = DateTime.Now;

Console.WriteLine(now);

DateTimeでは、主に次のようなことができます。

C#
DateTime now = DateTime.Now;

// 年月日を取得
int year = now.Year;
int month = now.Month;
int day = now.Day;

// 時刻を取得
int hour = now.Hour;
int minute = now.Minute;
int second = now.Second;

// 日付計算
DateTime tomorrow = now.AddDays(1);

// 文字列変換
string text = now.ToString("yyyy/MM/dd HH:mm:ss");

日付の取得、日時の表示、日時の比較、期間計算など、アプリケーション開発で必要になる日時処理の多くをDateTimeで実現できます。

1-2. DateTimeで扱える日付・時刻の範囲

DateTimeで扱える範囲は、次のとおりです。

C#
Console.WriteLine(DateTime.MinValue);
Console.WriteLine(DateTime.MaxValue);

出力例は次のようになります。

0001/01/01 0:00:00
9999/12/31 23:59:59

DateTime.MinValueは「0001年1月1日 00:00:00」、DateTime.MaxValueは「9999年12月31日 23:59:59.9999999」を表します。

注意したいのは、DateTime型の変数を初期化せずに使うと、既定値としてDateTime.MinValueが入る点です。

C#
DateTime date = default;

Console.WriteLine(date);

この場合、dateには0001/01/01 0:00:00が入ります。データベースや画面表示でこの値が出てきた場合、未設定の日付が意図せず使われている可能性があります。

1-3. DateTimeとstring・TimeSpan・DateTimeOffset・DateOnlyの違い

日付や時刻に関連する型はいくつかあります。それぞれ役割が異なるため、用途に応じて使い分けることが大切です。

DateTimeは、日付と時刻を表す型です。

C#
DateTime dateTime = new DateTime(2026, 6, 7, 10, 30, 0);

stringは文字列です。見た目としての日付を表すことはできますが、日付計算や正確な比較には向いていません。

C#
string dateText = "2026/06/07";

TimeSpanは、時間の長さや差分を表す型です。たとえば「3日間」「2時間30分」「開始日時と終了日時の差」を扱うときに使います。

C#
TimeSpan span = TimeSpan.FromHours(2);

DateTimeOffsetは、日時とUTCからのオフセットをセットで扱う型です。タイムゾーンや海外ユーザーの日時を扱う場合は、DateTimeよりDateTimeOffsetが適していることがあります。

C#
DateTimeOffset dto = DateTimeOffset.Now;

DateOnlyは日付だけを扱う型です。時刻が不要な誕生日、予約日、締切日などに向いています。

C#
DateOnly dateOnly = new DateOnly(2026, 6, 7);

TimeOnlyは時刻だけを扱う型です。営業時間や開始時刻など、日付を持たない時刻を表すときに使います。

C#
TimeOnly timeOnly = new TimeOnly(9, 30);

1-4. DateTimeを使う主な場面

DateTimeは、次のような場面でよく使われます。

C#
// 現在日時を取得する
DateTime now = DateTime.Now;

// ログ出力用の日時を作る
string logTime = now.ToString("yyyy-MM-dd HH:mm:ss");

// 有効期限を計算する
DateTime expiredAt = now.AddDays(30);

// 開始日時と終了日時の差を求める
DateTime start = new DateTime(2026, 6, 1);
DateTime end = new DateTime(2026, 6, 7);
TimeSpan diff = end - start;

代表的な用途は、ログの記録、予約システム、会員登録日、更新日時、締切日、請求日、APIの日時データ処理などです。

1-5. DateTimeを使う前に知っておきたい注意点

DateTimeを使うときは、次の点に注意しましょう。

まず、DateTimeにはKindという情報があります。これは、その日時がローカル時刻なのか、UTCなのか、未指定なのかを表します。

C#
DateTime now = DateTime.Now;
Console.WriteLine(now.Kind); // Local

DateTime utcNow = DateTime.UtcNow;
Console.WriteLine(utcNow.Kind); // Utc

また、日付だけを比較したい場合でも、DateTimeには時刻が含まれます。

C#
DateTime a = new DateTime(2026, 6, 7, 0, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 12, 0, 0);

Console.WriteLine(a == b); // False

このような場合は、.Dateを使って日付部分だけを比較します。

C#
Console.WriteLine(a.Date == b.Date); // True

さらに、文字列変換ではMMが月、mmが分を表します。ここを間違えると、表示結果が大きく変わります。

C#
DateTime now = DateTime.Now;

Console.WriteLine(now.ToString("yyyy/MM/dd HH:mm:ss")); // 正しい
Console.WriteLine(now.ToString("yyyy/mm/dd HH:MM:ss")); // 間違いやすい

2. C#で現在の日付・時刻を取得する方法

2-1. DateTime.Nowで現在の日時を取得する

現在のローカル日時を取得するには、DateTime.Nowを使います。

C#
DateTime now = DateTime.Now;

Console.WriteLine(now);

DateTime.Nowは、実行環境のローカルタイムゾーンに基づいた現在日時を返します。日本のPCや日本時間で動作しているサーバーであれば、日本時間の現在日時になります。

C#
DateTime now = DateTime.Now;

Console.WriteLine(now.Year);
Console.WriteLine(now.Month);
Console.WriteLine(now.Day);
Console.WriteLine(now.Hour);
Console.WriteLine(now.Minute);
Console.WriteLine(now.Second);

画面表示やローカル環境向けの日時表示では、DateTime.Nowがよく使われます。

2-2. DateTime.Todayで今日の日付だけを取得する

今日の日付だけを取得したい場合は、DateTime.Todayを使います。

C#
DateTime today = DateTime.Today;

Console.WriteLine(today);

DateTime.Todayは、今日の日付を返しますが、時刻部分は00:00:00になります。

C#
DateTime today = DateTime.Today;

Console.WriteLine(today.ToString("yyyy/MM/dd HH:mm:ss"));

出力例は次のようになります。

2026/06/07 00:00:00

「今日の日付を基準に処理したい」「日付だけを比較したい」という場合に便利です。

2-3. DateTime.UtcNowでUTC時刻を取得する

UTCの現在日時を取得するには、DateTime.UtcNowを使います。

C#
DateTime utcNow = DateTime.UtcNow;

Console.WriteLine(utcNow);
Console.WriteLine(utcNow.Kind);

UTCは協定世界時のことで、タイムゾーンに依存しない基準時刻として使われます。APIやデータベースに日時を保存する場合、UTCで保存しておくとタイムゾーンによるズレを避けやすくなります。

C#
DateTime savedAt = DateTime.UtcNow;

海外ユーザーを扱うWebサービスや、サーバーのタイムゾーンが変わる可能性があるシステムでは、DateTime.UtcNowを使う設計がよく採用されます。

2-4. 年・月・日・時・分・秒を個別に取得する

DateTimeから年、月、日、時、分、秒を個別に取得するには、各プロパティを使います。

C#
DateTime now = DateTime.Now;

int year = now.Year;
int month = now.Month;
int day = now.Day;
int hour = now.Hour;
int minute = now.Minute;
int second = now.Second;
int millisecond = now.Millisecond;

Console.WriteLine(year);
Console.WriteLine(month);
Console.WriteLine(day);
Console.WriteLine(hour);
Console.WriteLine(minute);
Console.WriteLine(second);
Console.WriteLine(millisecond);

年月日を個別に使いたい場合や、条件分岐に利用したい場合に便利です。

C#
DateTime now = DateTime.Now;

if (now.Hour < 12)
{
Console.WriteLine("午前です");
}
else
{
Console.WriteLine("午後です");
}

2-5. 曜日・日付のみ・時刻のみを取得する

曜日を取得するには、DayOfWeekプロパティを使います。

C#
DateTime now = DateTime.Now;

DayOfWeek dayOfWeek = now.DayOfWeek;

Console.WriteLine(dayOfWeek);

DayOfWeekは列挙型で、SundayMondayTuesdayなどを返します。

C#
if (now.DayOfWeek == DayOfWeek.Saturday ||
now.DayOfWeek == DayOfWeek.Sunday)
{
Console.WriteLine("土日です");
}

日付部分だけを取得するには、.Dateを使います。

C#
DateTime dateOnly = now.Date;

Console.WriteLine(dateOnly);

時刻部分だけを扱いたい場合は、TimeOfDayを使います。戻り値はTimeSpanです。

C#
TimeSpan timeOnly = now.TimeOfDay;

Console.WriteLine(timeOnly);

2-6. Now・Today・UtcNowの使い分け

DateTime.NowDateTime.TodayDateTime.UtcNowは似ていますが、用途が異なります。

C#
DateTime now = DateTime.Now;       // ローカルの現在日時
DateTime today = DateTime.Today; // ローカルの今日の日付、時刻は00:00:00
DateTime utcNow = DateTime.UtcNow; // UTCの現在日時

画面に現在日時を表示したい場合は、DateTime.Nowが使いやすいです。

C#
Console.WriteLine(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));

今日の日付だけで処理したい場合は、DateTime.Todayが便利です。

C#
DateTime today = DateTime.Today;

データベース保存、API連携、ログの基準時刻には、DateTime.UtcNowを使うと安全です。

C#
DateTime createdAt = DateTime.UtcNow;

3. DateTimeインスタンスを作成する方法

3-1. new DateTimeで任意の日付を作成する

任意の日付を作成するには、new DateTimeを使います。

C#
DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date);

この例では、2026年6月7日 00:00:00を表すDateTimeが作成されます。

年月日を指定するコンストラクターでは、時刻部分は自動的に00:00:00になります。

3-2. 年月日だけを指定して作成する

年月日だけを指定する基本形は次のとおりです。

C#
DateTime birthday = new DateTime(1990, 4, 15);

Console.WriteLine(birthday.ToString("yyyy/MM/dd"));

日付だけが必要な場合でも、DateTimeでは内部的に時刻を持ちます。この場合、時刻は00:00:00です。

C#
Console.WriteLine(birthday.ToString("yyyy/MM/dd HH:mm:ss"));

出力例は次のようになります。

1990/04/15 00:00:00

3-3. 年月日と時分秒を指定して作成する

年月日に加えて、時分秒も指定できます。

C#
DateTime meetingTime = new DateTime(2026, 6, 7, 14, 30, 0);

Console.WriteLine(meetingTime.ToString("yyyy/MM/dd HH:mm:ss"));

出力例は次のとおりです。

2026/06/07 14:30:00

予約日時、会議開始時刻、締切日時などを表すときに使います。

C#
DateTime deadline = new DateTime(2026, 6, 30, 23, 59, 59);

3-4. ミリ秒・Ticksを指定して作成する

ミリ秒まで指定したい場合は、次のようにします。

C#
DateTime dateTime = new DateTime(2026, 6, 7, 14, 30, 15, 500);

Console.WriteLine(dateTime.ToString("yyyy/MM/dd HH:mm:ss.fff"));

出力例は次のとおりです。

2026/06/07 14:30:15.500

さらに細かく、Ticksを使ってDateTimeを作成することもできます。

C#
DateTime now = DateTime.Now;
long ticks = now.Ticks;

DateTime restored = new DateTime(ticks);

Console.WriteLine(restored);

Ticksは、0001年1月1日 00:00:00からの経過時間を100ナノ秒単位で表す値です。通常の業務アプリケーションではあまり直接使いませんが、非常に細かい時刻管理や内部的な日時保存で使われることがあります。

3-5. DateTimeKindを指定してローカル時刻・UTCを区別する

DateTimeには、日時の種類を表すDateTimeKindを指定できます。

C#
DateTime localTime = new DateTime(
2026, 6, 7, 10, 0, 0, DateTimeKind.Local);

DateTime utcTime = new DateTime(
2026, 6, 7, 1, 0, 0, DateTimeKind.Utc);

DateTime unspecifiedTime = new DateTime(
2026, 6, 7, 10, 0, 0, DateTimeKind.Unspecified);

Console.WriteLine(localTime.Kind);
Console.WriteLine(utcTime.Kind);
Console.WriteLine(unspecifiedTime.Kind);

DateTimeKindには、次の3種類があります。

意味
Localローカル時刻
UtcUTC時刻
UnspecifiedローカルかUTCか未指定

特にToLocalTimeToUniversalTimeで変換するとき、Kindの値によって動作が変わります。APIやDBから取得した日時を扱う場合は、その日時がUTCなのかローカルなのかを明確にしておくことが重要です。

4. DateTimeを文字列に変換する方法

4-1. ToStringでDateTimeを文字列に変換する

DateTimeを文字列に変換するには、ToStringメソッドを使います。

C#
DateTime now = DateTime.Now;

string text = now.ToString();

Console.WriteLine(text);

そのままToString()を呼び出すと、実行環境のカルチャに応じた形式で出力されます。

表示形式を明確にしたい場合は、書式指定子を指定します。

C#
string formatted = now.ToString("yyyy/MM/dd HH:mm:ss");

Console.WriteLine(formatted);

実務では、表示形式が環境によって変わらないように、明示的にフォーマットを指定することが多いです。

4-2. yyyy/MM/dd形式で日付を表示する

日付をyyyy/MM/dd形式で表示するには、次のように書きます。

C#
DateTime date = new DateTime(2026, 6, 7);

string text = date.ToString("yyyy/MM/dd");

Console.WriteLine(text);

出力結果は次のとおりです。

2026/06/07

yyyyは4桁の年、MMは2桁の月、ddは2桁の日を表します。

C#
DateTime date = new DateTime(2026, 1, 5);

Console.WriteLine(date.ToString("yyyy/MM/dd")); // 2026/01/05
Console.WriteLine(date.ToString("yyyy/M/d")); // 2026/1/5

ゼロ埋めしたい場合はMMdd、ゼロ埋めしない場合はMdを使います。

4-3. yyyy-MM-dd HH:mm:ss形式で日時を表示する

日時をyyyy-MM-dd HH:mm:ss形式で表示するには、次のようにします。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 5, 9);

string text = now.ToString("yyyy-MM-dd HH:mm:ss");

Console.WriteLine(text);

出力結果は次のとおりです。

2026-06-07 14:05:09

この形式は、ログ、CSV、データベース確認用、管理画面などでよく使われます。

C#
string logMessage = $"処理日時: {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
Console.WriteLine(logMessage);

4-4. 年月日・曜日付きの日本語形式で表示する

日本語の年月日や曜日を付けて表示したい場合は、次のように書きます。

C#
DateTime date = new DateTime(2026, 6, 7);

string text = date.ToString("yyyy年M月d日 dddd");

Console.WriteLine(text);

日本語環境では、次のように表示されます。

2026年6月7日 日曜日

カルチャを明示する場合は、CultureInfoを指定します。

C#
using System.Globalization;

DateTime date = new DateTime(2026, 6, 7);

string text = date.ToString(
"yyyy年M月d日 dddd",
new CultureInfo("ja-JP"));

Console.WriteLine(text);

曜日を短く表示したい場合は、dddを使います。

C#
Console.WriteLine(date.ToString("yyyy年M月d日(ddd)", new CultureInfo("ja-JP")));

出力例は次のとおりです。

2026年6月7日(日)

4-5. 標準日時書式指定子の使い方

DateTimeには、標準日時書式指定子があります。1文字の指定子で、定義済みの形式に変換できます。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 30, 0);

Console.WriteLine(now.ToString("d")); // 短い日付形式
Console.WriteLine(now.ToString("D")); // 長い日付形式
Console.WriteLine(now.ToString("t")); // 短い時刻形式
Console.WriteLine(now.ToString("T")); // 長い時刻形式
Console.WriteLine(now.ToString("f")); // 長い日付と短い時刻
Console.WriteLine(now.ToString("F")); // 長い日付と長い時刻

標準書式指定子は、カルチャによって表示結果が変わります。ユーザーの地域設定に合わせた表示をしたい場合には便利ですが、ログやAPIのように固定形式が必要な場合は、カスタム書式を使うほうが安全です。

4-6. カスタム日時書式指定子の使い方

カスタム日時書式指定子を使うと、自由に表示形式を指定できます。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 5, 9);

Console.WriteLine(now.ToString("yyyy/MM/dd"));
Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss"));
Console.WriteLine(now.ToString("yyyy年M月d日 H時m分s秒"));
Console.WriteLine(now.ToString("HH:mm"));

よく使う指定子は次のとおりです。

指定子意味
yyyy4桁の年2026
MM2桁の月06
M6
dd2桁の日07
d7
HH24時間表記の時14
hh12時間表記の時02
mm05
ss09
fffミリ秒123
ddd短い曜日
dddd長い曜日日曜日

特に注意したいのは、月はMM、分はmmという点です。

4-7. 文字列補間でDateTimeをフォーマットする

文字列補間を使うと、DateTimeのフォーマットを簡潔に書けます。

C#
DateTime now = DateTime.Now;

string message = $"現在日時は {now:yyyy/MM/dd HH:mm:ss} です。";

Console.WriteLine(message);

ログやメッセージ作成では、次のように使うと読みやすくなります。

C#
DateTime startedAt = DateTime.Now;

Console.WriteLine($"処理開始: {startedAt:yyyy-MM-dd HH:mm:ss.fff}");

文字列補間では、変数名の後ろに:を書き、その後にフォーマットを指定します。

C#
$"{dateTime:yyyyMMdd}"

4-8. カルチャを指定して表示形式を制御する

日付の表示形式や曜日名、月名はカルチャによって変わります。カルチャを指定するには、CultureInfoを使います。

C#
using System.Globalization;

DateTime date = new DateTime(2026, 6, 7, 14, 30, 0);

Console.WriteLine(date.ToString("D", new CultureInfo("ja-JP")));
Console.WriteLine(date.ToString("D", new CultureInfo("en-US")));
Console.WriteLine(date.ToString("D", new CultureInfo("fr-FR")));

たとえば、英語の曜日や月名を表示したい場合は、en-USを指定します。

C#
using System.Globalization;

DateTime date = new DateTime(2026, 6, 7);

string text = date.ToString("dddd, MMMM d, yyyy", new CultureInfo("en-US"));

Console.WriteLine(text);

数値形式の固定フォーマットでログやAPIに出力する場合は、カルチャの影響を避けるためにCultureInfo.InvariantCultureを使うことがあります。

C#
using System.Globalization;

DateTime now = DateTime.Now;

string text = now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

Console.WriteLine(text);

5. 文字列をDateTimeに変換する方法

5-1. DateTime.Parseで文字列をDateTimeに変換する

文字列をDateTimeに変換するには、DateTime.Parseを使います。

C#
string text = "2026/06/07";

DateTime date = DateTime.Parse(text);

Console.WriteLine(date);

DateTime.Parseは、文字列を解析してDateTimeに変換します。ただし、変換できない文字列を渡すと例外が発生します。

C#
string text = "abc";

DateTime date = DateTime.Parse(text); // FormatException

入力値が必ず正しいと分かっている場合には使えますが、ユーザー入力や外部データを扱う場合は、TryParseを使うほうが安全です。

5-2. DateTime.TryParseで安全に変換する

例外を発生させずに安全に変換したい場合は、DateTime.TryParseを使います。

C#
string text = "2026/06/07";

bool success = DateTime.TryParse(text, out DateTime date);

if (success)
{
Console.WriteLine($"変換成功: {date}");
}
else
{
Console.WriteLine("変換失敗");
}

TryParseは、変換に成功した場合はtrue、失敗した場合はfalseを返します。

C#
string input = "invalid date";

if (DateTime.TryParse(input, out DateTime result))
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("正しい日付を入力してください。");
}

ユーザー入力フォーム、CSV、外部APIなど、形式が保証されない文字列にはTryParseが向いています。

5-3. DateTime.ParseExactで形式を指定して変換する

日付文字列の形式が決まっている場合は、ParseExactを使います。

C#
using System.Globalization;

string text = "2026-06-07";

DateTime date = DateTime.ParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture);

Console.WriteLine(date);

ParseExactは、指定した形式と完全に一致する文字列だけを変換します。

C#
string text = "2026/06/07";

DateTime date = DateTime.ParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture); // FormatException

この例では、文字列はyyyy/MM/ddなのに指定形式がyyyy-MM-ddなので変換に失敗します。

5-4. TryParseExactで例外を避けて変換する

形式を指定しつつ、例外を避けたい場合は、TryParseExactを使います。

C#
using System.Globalization;

string text = "2026-06-07";

bool success = DateTime.TryParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date);

if (success)
{
Console.WriteLine($"変換成功: {date}");
}
else
{
Console.WriteLine("変換失敗");
}

TryParseExactは、外部データの日付形式が決まっている場合に非常に便利です。

C#
string input = "20260607";

if (DateTime.TryParseExact(
input,
"yyyyMMdd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime result))
{
Console.WriteLine(result.ToString("yyyy/MM/dd"));
}

5-5. yyyyMMddなど区切りなしの日付文字列を変換する

20260607のような区切りなしの日付文字列は、ParseExactまたはTryParseExactで変換します。

C#
using System.Globalization;

string text = "20260607";

DateTime date = DateTime.ParseExact(
text,
"yyyyMMdd",
CultureInfo.InvariantCulture);

Console.WriteLine(date.ToString("yyyy/MM/dd"));

出力結果は次のとおりです。

2026/06/07

安全に変換する場合は、次のようにします。

C#
using System.Globalization;

string text = "20260607";

if (DateTime.TryParseExact(
text,
"yyyyMMdd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date))
{
Console.WriteLine(date.ToString("yyyy/MM/dd"));
}
else
{
Console.WriteLine("日付形式が正しくありません。");
}

CSVや固定長ファイルでは、yyyyMMdd形式の日付がよく使われます。

5-6. 変換に失敗する原因と対処法

文字列からDateTimeへの変換に失敗する主な原因は、形式の不一致です。

C#
string text = "2026-06-07";

DateTime.ParseExact(
text,
"yyyy/MM/dd",
CultureInfo.InvariantCulture); // 失敗

指定した形式がyyyy/MM/ddなのに、文字列がyyyy-MM-ddになっているため失敗します。

月と日の順序がカルチャによって解釈されるケースにも注意が必要です。

C#
string text = "06/07/2026";

DateTime date = DateTime.Parse(text);

このような文字列は、環境によって「6月7日」と解釈される場合もあれば、「7月6日」と解釈される可能性もあります。形式が決まっているなら、ParseExactで明示しましょう。

C#
DateTime date = DateTime.ParseExact(
text,
"MM/dd/yyyy",
CultureInfo.InvariantCulture);

空文字やnullにも注意します。

C#
string text = "";

if (DateTime.TryParse(text, out DateTime date))
{
Console.WriteLine(date);
}
else
{
Console.WriteLine("日付が未入力です。");
}

5-7. ユーザー入力・CSV・APIの日付文字列を扱うときの注意点

ユーザー入力や外部データの日付文字列を扱う場合は、基本的にParseよりTryParseTryParseExactを使いましょう。

C#
string input = "2026/06/07";

if (!DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine("日付形式が正しくありません。");
return;
}

Console.WriteLine(date);

CSVやAPIのように形式が決まっている場合は、TryParseExactでフォーマットを固定します。

C#
using System.Globalization;

string csvDate = "2026-06-07";

bool success = DateTime.TryParseExact(
csvDate,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date);

APIで日時を扱う場合は、タイムゾーンやUTCも確認が必要です。たとえば、2026-06-07T10:00:00Zのように末尾にZが付いている場合は、UTCを意味します。

C#
string apiDate = "2026-06-07T10:00:00Z";

DateTime date = DateTime.Parse(
apiDate,
null,
DateTimeStyles.AdjustToUniversal);

Console.WriteLine(date);

6. DateTimeを比較する方法

6-1. 比較演算子で日時の前後を判定する

DateTimeは、比較演算子で前後関係を判定できます。

C#
DateTime start = new DateTime(2026, 6, 1);
DateTime end = new DateTime(2026, 6, 7);

Console.WriteLine(start < end); // True
Console.WriteLine(start <= end); // True
Console.WriteLine(start > end); // False
Console.WriteLine(start >= end); // False

現在日時と比較して、期限切れかどうかを判定する例です。

C#
DateTime expiredAt = new DateTime(2026, 6, 30, 23, 59, 59);

if (DateTime.Now > expiredAt)
{
Console.WriteLine("期限切れです。");
}
else
{
Console.WriteLine("有効です。");
}

6-2. CompareToでDateTimeを比較する

CompareToを使って比較することもできます。

C#
DateTime date1 = new DateTime(2026, 6, 1);
DateTime date2 = new DateTime(2026, 6, 7);

int result = date1.CompareTo(date2);

Console.WriteLine(result);

CompareToの戻り値は次のようになります。

戻り値意味
0未満呼び出し元の日時が比較対象より前
0同じ日時
0より大きい呼び出し元の日時が比較対象より後
C#
if (date1.CompareTo(date2) < 0)
{
Console.WriteLine("date1はdate2より前です。");
}

6-3. Equalsで同じ日時か判定する

同じ日時かどうかを判定するには、Equalsまたは==を使います。

C#
DateTime a = new DateTime(2026, 6, 7, 10, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 10, 0, 0);

Console.WriteLine(a == b);
Console.WriteLine(a.Equals(b));

どちらも同じ日時であればtrueになります。

ただし、日付が同じでも時刻が異なる場合はfalseです。

C#
DateTime a = new DateTime(2026, 6, 7, 0, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 12, 0, 0);

Console.WriteLine(a == b); // False

6-4. 日付だけを比較する方法

日付だけを比較したい場合は、.Dateを使います。

C#
DateTime a = new DateTime(2026, 6, 7, 9, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 18, 30, 0);

if (a.Date == b.Date)
{
Console.WriteLine("同じ日付です。");
}

.Dateは、年月日部分はそのままで、時刻を00:00:00にしたDateTimeを返します。

C#
Console.WriteLine(a.Date.ToString("yyyy/MM/dd HH:mm:ss"));

出力例は次のとおりです。

2026/06/07 00:00:00

6-5. 時刻を無視して同じ日か判定する方法

時刻を無視して同じ日か判定する場合も、.Dateを使うのが簡単です。

C#
DateTime createdAt = new DateTime(2026, 6, 7, 23, 59, 59);
DateTime targetDate = new DateTime(2026, 6, 7, 0, 0, 0);

bool isSameDay = createdAt.Date == targetDate.Date;

Console.WriteLine(isSameDay);

今日作成されたデータかどうかを判定する場合は、次のように書けます。

C#
DateTime createdAt = new DateTime(2026, 6, 7, 15, 0, 0);

if (createdAt.Date == DateTime.Today)
{
Console.WriteLine("今日作成されたデータです。");
}

6-6. 期間内の日付かチェックする方法

指定した日時が期間内にあるかどうかは、比較演算子で判定できます。

C#
DateTime target = new DateTime(2026, 6, 7);
DateTime start = new DateTime(2026, 6, 1);
DateTime end = new DateTime(2026, 6, 30);

if (start <= target && target <= end)
{
Console.WriteLine("期間内です。");
}
else
{
Console.WriteLine("期間外です。");
}

終了日時を含めるか含めないかは、要件に応じて決めます。

C#
// 終了日時を含まない場合
if (start <= target && target < end)
{
Console.WriteLine("期間内です。");
}

日付だけで期間判定したい場合は、.Dateを使います。

C#
DateTime targetDate = target.Date;

if (start.Date <= targetDate && targetDate <= end.Date)
{
Console.WriteLine("日付が期間内です。");
}

6-7. 文字列のまま比較してはいけないケース

日付を文字列のまま比較すると、形式によっては正しく判定できません。

C#
string a = "2026/6/7";
string b = "2026/12/1";

Console.WriteLine(string.Compare(a, b) < 0);

文字列比較は文字の並びで比較するため、日付としての前後関係と一致しないことがあります。特に、月や日がゼロ埋めされていない場合は注意が必要です。

日付として比較する場合は、必ずDateTimeに変換してから比較しましょう。

C#
DateTime dateA = DateTime.Parse("2026/6/7");
DateTime dateB = DateTime.Parse("2026/12/1");

Console.WriteLine(dateA < dateB);

ただし、yyyyMMddyyyy-MM-ddのように桁数が固定され、年月日の順で並んでいる形式であれば、文字列比較でも順序が一致する場合があります。それでも実務では、日付として扱う値はDateTimeに変換して比較するほうが安全です。

7. DateTimeで日付・時刻を計算する方法

7-1. AddDaysで日数を加算・減算する

日数を加算するには、AddDaysを使います。

C#
DateTime today = DateTime.Today;

DateTime tomorrow = today.AddDays(1);
DateTime yesterday = today.AddDays(-1);

Console.WriteLine(tomorrow.ToString("yyyy/MM/dd"));
Console.WriteLine(yesterday.ToString("yyyy/MM/dd"));

AddDaysに正の値を渡すと未来の日付、負の値を渡すと過去の日付になります。

C#
DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.AddDays(7)); // 7日後
Console.WriteLine(date.AddDays(-30)); // 30日前

7-2. AddMonthsで月を加算・減算する

月を加算・減算するには、AddMonthsを使います。

C#
DateTime date = new DateTime(2026, 6, 7);

DateTime nextMonth = date.AddMonths(1);
DateTime previousMonth = date.AddMonths(-1);

Console.WriteLine(nextMonth.ToString("yyyy/MM/dd"));
Console.WriteLine(previousMonth.ToString("yyyy/MM/dd"));

月末の日付に対してAddMonthsを使う場合は、自動的に存在する日付に調整されます。

C#
DateTime date = new DateTime(2026, 1, 31);

DateTime nextMonth = date.AddMonths(1);

Console.WriteLine(nextMonth.ToString("yyyy/MM/dd"));

2026年2月31日は存在しないため、結果は2月末の日付になります。

7-3. AddYearsで年を加算・減算する

年を加算・減算するには、AddYearsを使います。

C#
DateTime date = new DateTime(2026, 6, 7);

DateTime nextYear = date.AddYears(1);
DateTime previousYear = date.AddYears(-1);

Console.WriteLine(nextYear.ToString("yyyy/MM/dd"));
Console.WriteLine(previousYear.ToString("yyyy/MM/dd"));

うるう日の扱いにも注意が必要です。

C#
DateTime leapDay = new DateTime(2024, 2, 29);

DateTime nextYear = leapDay.AddYears(1);

Console.WriteLine(nextYear.ToString("yyyy/MM/dd"));

2025年2月29日は存在しないため、結果は2025年2月28日になります。

7-4. AddHours・AddMinutes・AddSecondsで時刻を計算する

時間、分、秒を加算・減算するには、AddHoursAddMinutesAddSecondsを使います。

C#
DateTime now = new DateTime(2026, 6, 7, 10, 30, 0);

Console.WriteLine(now.AddHours(2));
Console.WriteLine(now.AddMinutes(30));
Console.WriteLine(now.AddSeconds(45));

負の値を指定すれば、過去の時刻を求められます。

C#
DateTime baseTime = new DateTime(2026, 6, 7, 10, 30, 0);

DateTime oneHourAgo = baseTime.AddHours(-1);
DateTime tenMinutesAgo = baseTime.AddMinutes(-10);

Console.WriteLine(oneHourAgo);
Console.WriteLine(tenMinutesAgo);

7-5. 2つのDateTimeの差分をTimeSpanで取得する

2つのDateTimeの差分は、引き算で求められます。結果はTimeSpanです。

C#
DateTime start = new DateTime(2026, 6, 1, 9, 0, 0);
DateTime end = new DateTime(2026, 6, 3, 18, 30, 0);

TimeSpan diff = end - start;

Console.WriteLine(diff.Days);
Console.WriteLine(diff.TotalDays);
Console.WriteLine(diff.TotalHours);
Console.WriteLine(diff.TotalMinutes);

Daysは日数部分、TotalDaysは合計日数を表します。

C#
TimeSpan span = new TimeSpan(1, 2, 30, 0);

Console.WriteLine(span.Days); // 1
Console.WriteLine(span.Hours); // 2
Console.WriteLine(span.TotalHours); // 26.5

合計時間を求める場合は、TotalHoursTotalMinutesを使います。

7-6. 経過日数・経過時間・残り時間を求める

経過日数を求めるには、現在日時から開始日時を引きます。

C#
DateTime startedAt = new DateTime(2026, 6, 1, 10, 0, 0);
DateTime now = DateTime.Now;

TimeSpan elapsed = now - startedAt;

Console.WriteLine($"経過日数: {elapsed.TotalDays}");
Console.WriteLine($"経過時間: {elapsed.TotalHours}");

締切までの残り時間を求めるには、終了日時から現在日時を引きます。

C#
DateTime deadline = new DateTime(2026, 6, 30, 23, 59, 59);
TimeSpan remaining = deadline - DateTime.Now;

if (remaining.TotalSeconds > 0)
{
Console.WriteLine($"残り日数: {remaining.TotalDays}");
}
else
{
Console.WriteLine("期限切れです。");
}

日数を整数で表示したい場合は、Math.CeilingMath.Floorを使うことがあります。

C#
int remainingDays = (int)Math.Ceiling(remaining.TotalDays);
Console.WriteLine($"残り{remainingDays}日");

7-7. 月末・月初・翌日・前日を求める

月初の日付は、年と月を使って1日を指定すれば求められます。

C#
DateTime date = DateTime.Today;

DateTime firstDay = new DateTime(date.Year, date.Month, 1);

Console.WriteLine(firstDay.ToString("yyyy/MM/dd"));

月末の日付は、翌月の月初から1日引くことで求められます。

C#
DateTime date = DateTime.Today;

DateTime firstDay = new DateTime(date.Year, date.Month, 1);
DateTime lastDay = firstDay.AddMonths(1).AddDays(-1);

Console.WriteLine(lastDay.ToString("yyyy/MM/dd"));

翌日と前日は、AddDaysで求められます。

C#
DateTime today = DateTime.Today;

DateTime tomorrow = today.AddDays(1);
DateTime yesterday = today.AddDays(-1);

Console.WriteLine(tomorrow.ToString("yyyy/MM/dd"));
Console.WriteLine(yesterday.ToString("yyyy/MM/dd"));

7-8. うるう年を考慮した日付計算

うるう年かどうかを判定するには、DateTime.IsLeapYearを使います。

C#
bool isLeapYear = DateTime.IsLeapYear(2024);

Console.WriteLine(isLeapYear); // True

うるう年を考慮して2月末を求める場合も、月末計算の方法を使えば安全です。

C#
int year = 2024;
int month = 2;

DateTime firstDay = new DateTime(year, month, 1);
DateTime lastDay = firstDay.AddMonths(1).AddDays(-1);

Console.WriteLine(lastDay.ToString("yyyy/MM/dd"));

出力結果は次のとおりです。

2024/02/29

日付計算では、月ごとの日数やうるう年を自分で分岐するより、AddMonthsAddDaysを組み合わせるほうが安全です。

8. DateTimeのフォーマット指定子一覧

8-1. よく使うDateTimeフォーマット早見表

DateTimeでよく使うフォーマットは次のとおりです。

フォーマット出力例用途
yyyy/MM/dd2026/06/07日付表示
yyyy-MM-dd2026-06-07API、DB、CSV
yyyyMMdd20260607ファイル名、固定長データ
HH:mm:ss14:30:05時刻表示
yyyy/MM/dd HH:mm:ss2026/06/07 14:30:05一般的な日時表示
yyyy-MM-dd HH:mm:ss2026-06-07 14:30:05ログ、DB確認
yyyy-MM-ddTHH:mm:ss2026-06-07T14:30:05ISO風の日時
yyyy年M月d日2026年6月7日日本語表示
yyyy年M月d日(ddd)2026年6月7日(日)曜日付き表示
HH:mm14:30時分表示
yyyyMMddHHmmss20260607143005ファイル名、ID生成

使用例は次のとおりです。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 30, 5);

Console.WriteLine(now.ToString("yyyy/MM/dd"));
Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss"));
Console.WriteLine(now.ToString("yyyyMMddHHmmss"));

8-2. 年を表すyyyy・yyの違い

年を表す代表的な指定子は、yyyyyyです。

C#
DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.ToString("yyyy")); // 2026
Console.WriteLine(date.ToString("yy")); // 26

yyyyは4桁の年、yyは下2桁の年を表します。

実務では、誤解を避けるためにyyyyを使うことが多いです。

C#
string fileName = $"log_{DateTime.Now:yyyyMMdd}.txt";

yyMMddのような形式は短くできますが、年の判別が曖昧になる場合があります。

8-3. 月を表すMM・M・MMM・MMMMの違い

月を表す指定子には、MMMMMMMMMMがあります。

C#
using System.Globalization;

DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.ToString("MM")); // 06
Console.WriteLine(date.ToString("M")); // 6

Console.WriteLine(date.ToString("MMM", new CultureInfo("en-US"))); // Jun
Console.WriteLine(date.ToString("MMMM", new CultureInfo("en-US"))); // June

MMは2桁の月、Mはゼロ埋めなしの月です。MMMMMMMは月名を表示します。

日本語表示では、次のように使うこともできます。

C#
Console.WriteLine(date.ToString("M月", new CultureInfo("ja-JP")));

8-4. 日を表すdd・dの違い

日を表す指定子には、dddがあります。

C#
DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.ToString("dd")); // 07
Console.WriteLine(date.ToString("d")); // 7

ddは2桁でゼロ埋め、dはゼロ埋めなしです。

ただし、dは単独で使うと標準日時書式指定子として解釈され、短い日付形式になる場合があります。

C#
DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.ToString("d")); // 短い日付形式
Console.WriteLine(date.ToString("%d")); // 日のみ
Console.WriteLine(date.ToString("yyyy/M/d"));

日だけを表示したい場合は、"%d"のように指定すると意図が明確になります。

8-5. 時刻を表すHH・hh・mm・ssの違い

時刻を表す指定子で特に重要なのが、HHhhmmssです。

C#
DateTime time = new DateTime(2026, 6, 7, 14, 5, 9);

Console.WriteLine(time.ToString("HH:mm:ss")); // 14:05:09
Console.WriteLine(time.ToString("hh:mm:ss")); // 02:05:09

HHは24時間表記、hhは12時間表記です。

指定子意味
HH24時間表記の時
H24時間表記の時、ゼロ埋めなし
hh12時間表記の時
h12時間表記の時、ゼロ埋めなし
mm
ss

12時間表記で午前・午後を表示したい場合は、ttを使います。

C#
using System.Globalization;

DateTime time = new DateTime(2026, 6, 7, 14, 5, 9);

Console.WriteLine(time.ToString("tt hh:mm", new CultureInfo("ja-JP")));

8-6. 曜日を表すddd・ddddの使い方

曜日を表示するには、dddまたはddddを使います。

C#
using System.Globalization;

DateTime date = new DateTime(2026, 6, 7);

Console.WriteLine(date.ToString("ddd", new CultureInfo("ja-JP")));
Console.WriteLine(date.ToString("dddd", new CultureInfo("ja-JP")));

出力例は次のとおりです。


日曜日

英語の曜日を表示する場合は、en-USなどのカルチャを指定します。

C#
Console.WriteLine(date.ToString("ddd", new CultureInfo("en-US")));   // Sun
Console.WriteLine(date.ToString("dddd", new CultureInfo("en-US"))); // Sunday

曜日付きの日付表示は、次のように書くと実務でも使いやすいです。

C#
string text = date.ToString("yyyy/MM/dd(ddd)", new CultureInfo("ja-JP"));

8-7. ミリ秒・タイムゾーンを表す書式指定子

ミリ秒を表示するには、fffを使います。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 30, 5, 123);

Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss.fff"));

出力例は次のとおりです。

2026-06-07 14:30:05.123

より細かい桁まで表示したい場合は、fffffffまで指定できます。

C#
Console.WriteLine(now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));

タイムゾーンやUTCオフセットに関係する指定子には、Kzzzがあります。

C#
DateTime local = DateTime.Now;
DateTime utc = DateTime.UtcNow;

Console.WriteLine(local.ToString("yyyy-MM-ddTHH:mm:ssK"));
Console.WriteLine(utc.ToString("yyyy-MM-ddTHH:mm:ssK"));

ただし、DateTimeでタイムゾーンを厳密に扱う場合は注意が必要です。UTCオフセットを明確に扱いたい場合は、DateTimeOffsetを検討しましょう。

8-8. 実務でよく使うフォーマット例

実務では、用途ごとにフォーマットを使い分けます。

ログ出力では、秒やミリ秒まで含めることが多いです。

C#
string logTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
Console.WriteLine(logTime);

ファイル名に日時を含める場合は、記号を避けてyyyyMMddHHmmss形式にすることがあります。

C#
string fileName = $"backup_{DateTime.Now:yyyyMMddHHmmss}.csv";
Console.WriteLine(fileName);

画面表示では、日本語の読みやすい形式にできます。

C#
using System.Globalization;

string display = DateTime.Now.ToString(
"yyyy年M月d日(ddd) H時m分",
new CultureInfo("ja-JP"));

Console.WriteLine(display);

APIやDB保存向けには、UTCでISO 8601に近い形式を使うことがあります。

C#
string apiDate = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");
Console.WriteLine(apiDate);

9. DateTimeのタイムゾーンとUTCの扱い方

9-1. ローカル時刻とUTCの違い

ローカル時刻は、実行環境のタイムゾーンに基づく日時です。日本であれば通常は日本時間になります。

C#
DateTime localNow = DateTime.Now;
Console.WriteLine(localNow);

UTCは協定世界時で、世界共通の基準となる時刻です。

C#
DateTime utcNow = DateTime.UtcNow;
Console.WriteLine(utcNow);

日本時間はUTCより9時間進んでいます。そのため、日本時間の2026/06/07 18:00:00は、UTCでは2026/06/07 09:00:00になります。

システム内部ではUTCで保存し、画面表示時にユーザーのローカル時刻へ変換する設計がよく使われます。

9-2. DateTimeKindとは何か

DateTimeKindは、DateTimeがローカル時刻なのか、UTCなのか、未指定なのかを表します。

C#
DateTime local = DateTime.Now;
DateTime utc = DateTime.UtcNow;
DateTime unspecified = new DateTime(2026, 6, 7, 10, 0, 0);

Console.WriteLine(local.Kind); // Local
Console.WriteLine(utc.Kind); // Utc
Console.WriteLine(unspecified.Kind); // Unspecified

DateTimeKindには次の3種類があります。

Kind意味
Localローカル時刻
UtcUTC時刻
Unspecified種別未指定

DateTimeKindは、日時の値そのものにタイムゾーン情報を完全に持たせるものではありません。あくまで、そのDateTimeをどの種類の時刻として扱うかを示す情報です。

9-3. ToLocalTimeでローカル時刻に変換する

UTCのDateTimeをローカル時刻に変換するには、ToLocalTimeを使います。

C#
DateTime utcNow = DateTime.UtcNow;

DateTime localTime = utcNow.ToLocalTime();

Console.WriteLine(utcNow);
Console.WriteLine(localTime);

ToLocalTimeは、DateTimeKindを見て変換します。KindUtcの場合は、ローカル時刻に変換されます。

C#
DateTime utc = new DateTime(2026, 6, 7, 9, 0, 0, DateTimeKind.Utc);
DateTime local = utc.ToLocalTime();

Console.WriteLine(local);

日本時間の環境では、9時間加算された時刻になります。

9-4. ToUniversalTimeでUTCに変換する

ローカル時刻をUTCに変換するには、ToUniversalTimeを使います。

C#
DateTime localNow = DateTime.Now;

DateTime utcNow = localNow.ToUniversalTime();

Console.WriteLine(localNow);
Console.WriteLine(utcNow);

KindLocalの場合、ローカルタイムゾーンからUTCへ変換されます。

C#
DateTime local = new DateTime(2026, 6, 7, 18, 0, 0, DateTimeKind.Local);
DateTime utc = local.ToUniversalTime();

Console.WriteLine(utc);

注意点として、KindUnspecifiedの場合、ToUniversalTimeではローカル時刻として扱われます。外部データから取得した日時がUTCなのかローカルなのか不明な場合は、変換前に仕様を確認しましょう。

9-5. TimeZoneInfoでタイムゾーン変換する

特定のタイムゾーンに変換したい場合は、TimeZoneInfoを使います。

C#
DateTime utcTime = DateTime.UtcNow;

TimeZoneInfo tokyoTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");

DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, tokyoTimeZone);

Console.WriteLine(tokyoTime);

Windows環境では、日本時間のタイムゾーンIDとして"Tokyo Standard Time"を使います。

ローカル時刻からUTCへ変換する場合は、次のようにできます。

C#
TimeZoneInfo tokyoTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");

DateTime tokyoTime = new DateTime(2026, 6, 7, 18, 0, 0);

DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(tokyoTime, tokyoTimeZone);

Console.WriteLine(utcTime);

複数地域のユーザーを扱う場合は、サーバーのローカル時刻に依存せず、TimeZoneInfoで明示的に変換することが重要です。

9-6. 海外ユーザー・サーバー時刻を扱うときの注意点

海外ユーザーやクラウドサーバーを扱う場合、サーバーのローカル時刻が日本時間とは限りません。

C#
DateTime now = DateTime.Now;

このコードは、実行環境のローカル時刻を返します。日本の開発PCでは日本時間でも、本番サーバーではUTCになっている可能性があります。

そのため、データ保存にはUTCを使うのが安全です。

C#
DateTime createdAt = DateTime.UtcNow;

画面表示時に、ユーザーのタイムゾーンへ変換します。

C#
DateTime utc = DateTime.UtcNow;

TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, timeZone);

Console.WriteLine(local);

海外ユーザーを対象にする場合は、「保存はUTC、表示はユーザーのタイムゾーン」という方針を基本にすると、日時のズレを防ぎやすくなります。

9-7. DateTimeOffsetを使うべきケース

DateTimeOffsetは、日時とUTCからのオフセットをセットで扱う型です。

C#
DateTimeOffset now = DateTimeOffset.Now;

Console.WriteLine(now);
Console.WriteLine(now.Offset);

たとえば、日本時間の2026-06-07 18:00:00 +09:00のように、日時とオフセットを同時に表せます。

APIで日時をやり取りする場合や、海外ユーザーのローカル時刻を正確に扱いたい場合は、DateTimeよりDateTimeOffsetが適していることがあります。

C#
DateTimeOffset dto = DateTimeOffset.UtcNow;

Console.WriteLine(dto.ToString("o"));

タイムゾーンやオフセットの情報が重要なシステムでは、DateTimeOffsetの利用を検討しましょう。

10. DateTimeでよくあるエラー・ハマりどころ

10-1. 文字列からDateTimeに変換できない

文字列をDateTimeに変換できない原因の多くは、日付形式の不一致です。

C#
string text = "2026-06-07";

DateTime date = DateTime.ParseExact(
text,
"yyyy/MM/dd",
CultureInfo.InvariantCulture);

この例では、文字列はyyyy-MM-dd形式ですが、指定しているフォーマットはyyyy/MM/ddなので失敗します。

正しくは次のようにします。

C#
using System.Globalization;

string text = "2026-06-07";

DateTime date = DateTime.ParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture);

外部入力では、例外を防ぐためにTryParseExactを使いましょう。

C#
bool success = DateTime.TryParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime result);

10-2. 月と分の書式指定を間違える

DateTimeのフォーマットで非常によくあるミスが、月と分の指定子の混同です。

月はMM、分はmmです。

C#
DateTime now = new DateTime(2026, 6, 7, 14, 5, 0);

Console.WriteLine(now.ToString("yyyy/MM/dd HH:mm")); // 正しい
Console.WriteLine(now.ToString("yyyy/mm/dd HH:MM")); // 間違い

yyyy/mm/ddと書くと、月ではなく分が表示されます。

正しくは次のとおりです。

C#
string text = now.ToString("yyyy/MM/dd HH:mm");

日付フォーマットでは、大文字と小文字の違いが重要です。

10-3. 12時間表記と24時間表記を間違える

時を表す指定子には、HHhhがあります。

C#
DateTime time = new DateTime(2026, 6, 7, 14, 30, 0);

Console.WriteLine(time.ToString("HH:mm")); // 14:30
Console.WriteLine(time.ToString("hh:mm")); // 02:30

HHは24時間表記、hhは12時間表記です。

12時間表記を使う場合は、午前・午後を表すttも付けると分かりやすくなります。

C#
using System.Globalization;

Console.WriteLine(time.ToString("tt hh:mm", new CultureInfo("ja-JP")));

ログやDB保存用の日時では、通常はHH:mm:ssを使うのが安全です。

10-4. 日付だけ比較したいのに時刻まで比較してしまう

DateTimeには時刻も含まれるため、同じ日付でも時刻が異なれば別の値として扱われます。

C#
DateTime a = new DateTime(2026, 6, 7, 0, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 12, 0, 0);

Console.WriteLine(a == b); // False

日付だけ比較したい場合は、.Dateを使います。

C#
Console.WriteLine(a.Date == b.Date); // True

今日の日付かどうかを判定する場合も、次のようにします。

C#
DateTime createdAt = new DateTime(2026, 6, 7, 15, 30, 0);

if (createdAt.Date == DateTime.Today)
{
Console.WriteLine("今日のデータです。");
}

10-5. タイムゾーンの違いで日時がずれる

日時がずれる原因として多いのが、ローカル時刻とUTCの混在です。

C#
DateTime local = DateTime.Now;
DateTime utc = DateTime.UtcNow;

この2つは同じ瞬間を表していても、表示される時刻が異なります。日本時間では通常、ローカル時刻はUTCより9時間進んでいます。

APIやDBに保存するときはUTCに統一し、表示時にローカル時刻へ変換すると管理しやすくなります。

C#
DateTime savedAt = DateTime.UtcNow;

DateTime displayTime = savedAt.ToLocalTime();

ただし、Kindが正しく設定されていないと、変換結果が意図しないものになる場合があります。日時がUTCなのかローカルなのかを明確に扱いましょう。

10-6. nullを扱いたい場合はNullable DateTimeを使う

DateTimeは値型なので、そのままではnullを代入できません。

C#
DateTime date = null; // コンパイルエラー

未設定を表したい場合は、DateTime?を使います。

C#
DateTime? date = null;

if (date.HasValue)
{
Console.WriteLine(date.Value);
}
else
{
Console.WriteLine("日付は未設定です。");
}

DateTime?は、Nullable<DateTime>の省略形です。

C#
Nullable<DateTime> date = null;

データベースで日付がNULLになる可能性がある場合や、任意入力の日付フォームではDateTime?を使うのが一般的です。

10-7. DateTime.MinValueが意図せず入る原因

DateTimeの既定値はDateTime.MinValueです。

C#
DateTime date = default;

Console.WriteLine(date);

出力例は次のとおりです。

0001/01/01 0:00:00

未設定のつもりでDateTimeを使っていると、0001/01/01が画面やデータベースに入ってしまうことがあります。

未設定を表したい場合は、DateTime?を使いましょう。

C#
DateTime? date = null;

また、変換に失敗したときにDateTime.MinValueを代入する設計にしていると、本来のデータ不備に気づきにくくなります。

C#
DateTime date;

if (!DateTime.TryParse("invalid", out date))
{
date = DateTime.MinValue;
}

このような場合は、失敗時にエラーメッセージを返す、またはDateTime?nullにするほうが安全です。

11. DateTimeの実務で使えるサンプルコード集

11-1. 今日・昨日・明日の日付を取得する

今日、昨日、明日の日付は、DateTime.TodayAddDaysで取得できます。

C#
DateTime today = DateTime.Today;
DateTime yesterday = today.AddDays(-1);
DateTime tomorrow = today.AddDays(1);

Console.WriteLine($"今日: {today:yyyy/MM/dd}");
Console.WriteLine($"昨日: {yesterday:yyyy/MM/dd}");
Console.WriteLine($"明日: {tomorrow:yyyy/MM/dd}");

時刻を含めた現在日時が必要な場合は、DateTime.Nowを使います。

C#
DateTime now = DateTime.Now;

Console.WriteLine($"現在日時: {now:yyyy/MM/dd HH:mm:ss}");

11-2. 現在日時をログ用フォーマットで出力する

ログ用には、並び替えしやすいyyyy-MM-dd HH:mm:ss.fff形式がよく使われます。

C#
DateTime now = DateTime.Now;

string logTime = now.ToString("yyyy-MM-dd HH:mm:ss.fff");

Console.WriteLine($"[{logTime}] 処理を開始しました。");

UTCでログを出力する場合は、DateTime.UtcNowを使います。

C#
string logTime = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");

Console.WriteLine($"[{logTime} UTC] 処理を開始しました。");

ファイル名に日時を含める場合は、記号を少なくした形式が便利です。

C#
string fileName = $"log_{DateTime.Now:yyyyMMddHHmmss}.txt";

Console.WriteLine(fileName);

11-3. 入力された日付が正しいか検証する

ユーザーが入力した日付が正しいか検証するには、TryParseを使います。

C#
string input = "2026/06/07";

if (DateTime.TryParse(input, out DateTime date))
{
Console.WriteLine($"正しい日付です: {date:yyyy/MM/dd}");
}
else
{
Console.WriteLine("日付の形式が正しくありません。");
}

形式をyyyy-MM-ddに限定する場合は、TryParseExactを使います。

C#
using System.Globalization;

string input = "2026-06-07";

bool isValid = DateTime.TryParseExact(
input,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date);

if (isValid)
{
Console.WriteLine($"正しい日付です: {date:yyyy/MM/dd}");
}
else
{
Console.WriteLine("yyyy-MM-dd形式で入力してください。");
}

11-4. 生年月日から年齢を計算する

生年月日から年齢を計算するには、現在年から生年を引き、誕生日がまだ来ていない場合に1を引きます。

C#
DateTime birthDate = new DateTime(1990, 6, 20);
DateTime today = DateTime.Today;

int age = today.Year - birthDate.Year;

if (birthDate.Date > today.AddYears(-age))
{
age--;
}

Console.WriteLine($"年齢: {age}");

メソッド化すると再利用しやすくなります。

C#
static int CalculateAge(DateTime birthDate, DateTime today)
{
int age = today.Year - birthDate.Year;

if (birthDate.Date > today.AddYears(-age))
{
age--;
}

return age;
}

int age = CalculateAge(new DateTime(1990, 6, 20), DateTime.Today);
Console.WriteLine(age);

11-5. 開始日と終了日から期間を計算する

開始日と終了日の差分は、TimeSpanで取得できます。

C#
DateTime startDate = new DateTime(2026, 6, 1);
DateTime endDate = new DateTime(2026, 6, 7);

TimeSpan period = endDate - startDate;

Console.WriteLine($"差分日数: {period.TotalDays}");

開始日と終了日を両方含めて日数を数える場合は、1日加算します。

C#
int daysInclusive = (endDate.Date - startDate.Date).Days + 1;

Console.WriteLine($"期間日数: {daysInclusive}");

たとえば、6月1日から6月7日までを両端含めて数えると7日間になります。

11-6. 月初・月末の日付を取得する

指定日の月初を取得するには、日を1にします。

C#
DateTime date = DateTime.Today;

DateTime firstDay = new DateTime(date.Year, date.Month, 1);

Console.WriteLine($"月初: {firstDay:yyyy/MM/dd}");

月末は、翌月の月初から1日引いて求めます。

C#
DateTime lastDay = firstDay.AddMonths(1).AddDays(-1);

Console.WriteLine($"月末: {lastDay:yyyy/MM/dd}");

メソッド化すると便利です。

C#
static DateTime GetFirstDayOfMonth(DateTime date)
{
return new DateTime(date.Year, date.Month, 1);
}

static DateTime GetLastDayOfMonth(DateTime date)
{
DateTime firstDay = GetFirstDayOfMonth(date);
return firstDay.AddMonths(1).AddDays(-1);
}

11-7. 指定日が土日か判定する

指定日が土日かどうかは、DayOfWeekで判定します。

C#
DateTime date = new DateTime(2026, 6, 7);

bool isWeekend =
date.DayOfWeek == DayOfWeek.Saturday ||
date.DayOfWeek == DayOfWeek.Sunday;

Console.WriteLine(isWeekend);

メソッド化すると読みやすくなります。

C#
static bool IsWeekend(DateTime date)
{
return date.DayOfWeek == DayOfWeek.Saturday ||
date.DayOfWeek == DayOfWeek.Sunday;
}

if (IsWeekend(DateTime.Today))
{
Console.WriteLine("今日は土日です。");
}
else
{
Console.WriteLine("今日は平日です。");
}

祝日判定が必要な場合は、別途祝日マスタやライブラリを使って判定します。DateTime単体では日本の祝日かどうかは分かりません。

11-8. APIやDB保存向けにUTCで扱う

APIやデータベースに保存する日時は、UTCに統一すると扱いやすくなります。

C#
DateTime createdAt = DateTime.UtcNow;
DateTime updatedAt = DateTime.UtcNow;

保存されたUTC日時を画面表示するときは、ローカル時刻に変換します。

C#
DateTime savedUtc = DateTime.UtcNow;

DateTime localTime = savedUtc.ToLocalTime();

Console.WriteLine(localTime.ToString("yyyy/MM/dd HH:mm:ss"));

特定のタイムゾーンに変換する場合は、TimeZoneInfoを使います。

C#
DateTime utc = DateTime.UtcNow;

TimeZoneInfo tokyoTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");

DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tokyoTimeZone);

Console.WriteLine(tokyoTime.ToString("yyyy/MM/dd HH:mm:ss"));

UTC保存を徹底すると、サーバー移行や海外展開時の日時トラブルを減らせます。

12. DateTimeと関連クラスの使い分け

12-1. DateTimeを使うべきケース

DateTimeは、日付と時刻をまとめて扱いたい場合に適しています。

C#
DateTime createdAt = DateTime.Now;
DateTime expiredAt = DateTime.Now.AddDays(30);

具体的には、次のようなケースです。

用途
作成日時会員登録日時
更新日時データ更新日時
予約日時2026/06/07 14:00
締切日時2026/06/30 23:59
ログ日時処理開始時刻

ただし、タイムゾーンやUTCオフセットを厳密に扱う場合は、DateTimeOffsetも検討しましょう。

12-2. DateTimeOffsetを使うべきケース

DateTimeOffsetは、日時とUTCからのオフセットを一緒に扱いたい場合に使います。

C#
DateTimeOffset now = DateTimeOffset.Now;

Console.WriteLine(now);
Console.WriteLine(now.Offset);

次のようなケースでは、DateTimeOffsetが向いています。

用途理由
API連携オフセット付き日時を扱いやすい
海外ユーザー対応ユーザーのローカル時刻を保持しやすい
イベント日時管理UTCとの差を明確にできる
ログ・監査どのオフセットの時刻か分かりやすい

たとえば、ISO 8601形式で出力する場合は次のようにできます。

C#
DateTimeOffset now = DateTimeOffset.Now;

Console.WriteLine(now.ToString("o"));

12-3. TimeSpanを使うべきケース

TimeSpanは、日時そのものではなく、時間の長さや差分を表す型です。

C#
TimeSpan duration = TimeSpan.FromHours(2);

Console.WriteLine(duration.TotalMinutes);

次のようなケースで使います。

用途
処理時間処理に3.5秒かかった
経過時間開始から2時間経過
残り時間締切まで5日
時間差終了日時 - 開始日時
待機時間30分後に実行

DateTime同士を引くと、結果はTimeSpanになります。

C#
DateTime start = DateTime.Now;

// 何らかの処理

DateTime end = DateTime.Now;
TimeSpan elapsed = end - start;

Console.WriteLine(elapsed.TotalSeconds);

12-4. DateOnlyを使うべきケース

DateOnlyは、日付だけを扱う型です。時刻が不要なデータには、DateTimeより意図が明確になります。

C#
DateOnly birthday = new DateOnly(1990, 6, 7);

Console.WriteLine(birthday);

次のようなケースに向いています。

用途
生年月日1990/06/07
予約日2026/06/07
締切日2026/06/30
営業日2026/06/07
記念日2026/10/01

DateTimeで日付だけを扱うと、時刻部分の00:00:00が比較や表示で影響する場合があります。時刻が不要ならDateOnlyを使うと、コードの意図が分かりやすくなります。

12-5. TimeOnlyを使うべきケース

TimeOnlyは、時刻だけを扱う型です。日付を持たない時刻を表すときに使います。

C#
TimeOnly openingTime = new TimeOnly(9, 0);
TimeOnly closingTime = new TimeOnly(18, 0);

Console.WriteLine(openingTime);
Console.WriteLine(closingTime);

次のようなケースに向いています。

用途
営業開始時刻09:00
営業終了時刻18:00
毎日の実行時刻03:00
授業開始時刻10:30
シフト開始時刻08:00

日付が不要なのにDateTimeを使うと、意味のない日付が混ざる可能性があります。時刻だけを表したい場合は、TimeOnlyが適しています。

12-6. データベース保存時の日付型の選び方

データベースに日付を保存する場合は、用途に応じて型を選びます。

用途C#の型保存方針
作成日時・更新日時DateTimeまたはDateTimeOffsetUTC保存が基本
生年月日DateOnlyまたはDateTime日付のみ
予約日時DateTimeまたはDateTimeOffsetタイムゾーン要件を確認
処理時間TimeSpan秒数やミリ秒で保存する場合もある
営業時間TimeOnly時刻のみ

シンプルな国内向け業務システムではDateTimeで十分な場合もありますが、海外ユーザーやAPI連携がある場合は、UTC保存やDateTimeOffsetの利用を検討しましょう。

C#
public class User
{
public int Id { get; set; }

public DateTime CreatedAtUtc { get; set; }

public DateTime? LastLoginAtUtc { get; set; }
}

未設定の可能性がある日時は、DateTime?を使うと安全です。

13. C# DateTimeに関するよくある質問

13-1. DateTime.NowとDateTime.Todayの違いは?

DateTime.Nowは現在の日付と時刻を返します。

C#
DateTime now = DateTime.Now;

Console.WriteLine(now.ToString("yyyy/MM/dd HH:mm:ss"));

一方、DateTime.Todayは今日の日付を返し、時刻は00:00:00になります。

C#
DateTime today = DateTime.Today;

Console.WriteLine(today.ToString("yyyy/MM/dd HH:mm:ss"));

現在時刻まで必要な場合はDateTime.Now、今日の日付だけが必要な場合はDateTime.Todayを使います。

13-2. DateTimeをyyyyMMdd形式に変換するには?

ToString("yyyyMMdd")を使います。

C#
DateTime date = new DateTime(2026, 6, 7);

string text = date.ToString("yyyyMMdd");

Console.WriteLine(text);

出力結果は次のとおりです。

20260607

ファイル名や固定長データでよく使われる形式です。

C#
string fileName = $"data_{DateTime.Now:yyyyMMdd}.csv";

13-3. stringをDateTimeに変換するには?

文字列をDateTimeに変換するには、DateTime.ParseまたはDateTime.TryParseを使います。

C#
string text = "2026/06/07";

DateTime date = DateTime.Parse(text);

Console.WriteLine(date);

安全に変換する場合は、TryParseを使います。

C#
string text = "2026/06/07";

if (DateTime.TryParse(text, out DateTime date))
{
Console.WriteLine(date);
}
else
{
Console.WriteLine("変換できませんでした。");
}

形式が決まっている場合は、TryParseExactが適しています。

C#
using System.Globalization;

string text = "2026-06-07";

bool success = DateTime.TryParseExact(
text,
"yyyy-MM-dd",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime date);

13-4. DateTimeの日付だけを比較するには?

日付だけを比較するには、.Dateを使います。

C#
DateTime a = new DateTime(2026, 6, 7, 9, 0, 0);
DateTime b = new DateTime(2026, 6, 7, 18, 0, 0);

bool sameDate = a.Date == b.Date;

Console.WriteLine(sameDate);

時刻が異なっていても、日付が同じならtrueになります。

C#
if (a.Date == DateTime.Today)
{
Console.WriteLine("今日の日付です。");
}

13-5. DateTimeに1日加算するには?

AddDays(1)を使います。

C#
DateTime today = DateTime.Today;

DateTime tomorrow = today.AddDays(1);

Console.WriteLine(tomorrow.ToString("yyyy/MM/dd"));

1日前にしたい場合は、AddDays(-1)を使います。

C#
DateTime yesterday = today.AddDays(-1);

13-6. DateTimeの差分を日数で取得するには?

2つのDateTimeを引くと、TimeSpanが取得できます。

C#
DateTime start = new DateTime(2026, 6, 1);
DateTime end = new DateTime(2026, 6, 7);

TimeSpan diff = end - start;

Console.WriteLine(diff.Days);
Console.WriteLine(diff.TotalDays);

Daysは日数部分、TotalDaysは合計日数です。通常、差分を日数として扱う場合はTotalDaysまたは.Daysを要件に応じて使います。

整数の日数が必要な場合は、次のようにできます。

C#
int days = (end.Date - start.Date).Days;

Console.WriteLine(days);

13-7. DateTimeでnullを扱うには?

DateTimeは値型なので、そのままではnullを扱えません。nullを許可したい場合は、DateTime?を使います。

C#
DateTime? date = null;

if (date.HasValue)
{
Console.WriteLine(date.Value.ToString("yyyy/MM/dd"));
}
else
{
Console.WriteLine("日付は未設定です。");
}

代入するときは通常のDateTimeと同じように書けます。

C#
date = DateTime.Today;

DateTime?は、任意入力の日付や、データベースでNULLを許可する日時カラムに対応する場合によく使います。

13-8. DateTimeとDateTimeOffsetはどちらを使うべき?

単純に日付と時刻を扱うだけであれば、DateTimeで十分なことが多いです。

C#
DateTime now = DateTime.Now;

一方で、UTCからのオフセットを明確に扱いたい場合や、海外ユーザー、API連携、タイムゾーンを意識するシステムでは、DateTimeOffsetが適しています。

C#
DateTimeOffset now = DateTimeOffset.Now;

Console.WriteLine(now);
Console.WriteLine(now.Offset);

目安としては、次のように考えると分かりやすいです。

向いているケース
DateTimeローカルな日時、単純な日時管理
DateTimeOffsetUTCオフセットが重要な日時管理
DateOnly日付だけが必要
TimeOnly時刻だけが必要
TimeSpan時間の長さや差分が必要

APIやDB保存では、UTCで統一するか、DateTimeOffsetでオフセットを保持するかを設計段階で決めておくことが重要です。

まとめ

C#のDateTimeは、日付と時刻を扱うための基本的な型です。現在日時の取得、任意の日付作成、文字列変換、比較、日付計算、フォーマット指定など、実務で必要になる多くの日時処理を実現できます。

現在日時を取得する場合は、ローカル時刻ならDateTime.Now、今日の日付だけならDateTime.Today、UTC時刻ならDateTime.UtcNowを使います。任意の日付を作る場合は、new DateTime(年, 月, 日)new DateTime(年, 月, 日, 時, 分, 秒)を使います。

文字列に変換する場合は、ToString("yyyy/MM/dd")ToString("yyyy-MM-dd HH:mm:ss")のようにフォーマットを指定します。文字列から変換する場合は、Parseよりも、例外を避けられるTryParseTryParseExactを使うと安全です。

比較では、<>==などの比較演算子が使えます。ただし、DateTimeには時刻も含まれるため、日付だけを比較したい場合は.Dateを使いましょう。

日付計算では、AddDaysAddMonthsAddYearsAddHoursなどを使います。2つの日時の差分はTimeSpanで取得できます。月末やうるう年の計算では、自分で日数を判定するより、AddMonthsAddDaysを組み合わせるほうが安全です。

また、タイムゾーンを扱う場合は、DateTimeKindToLocalTimeToUniversalTimeTimeZoneInfoを理解しておく必要があります。海外ユーザーやAPI連携、データベース保存では、UTCで保存するか、DateTimeOffsetを使う設計を検討しましょう。

DateTimeはシンプルに見えますが、フォーマット、比較、タイムゾーン、nullの扱いでミスが起きやすい型です。基本を押さえておけば、C#の日付・時刻処理を安全かつ分かりやすく実装できます。