日時

DateTime 構造体

時間の情報が不要ならば、DateOnly構造体を用います。DateOnly 構造体 - 日付と時刻に関連する型を比較する - .NET | Microsoft Learn

コンストラクタ

public DateTime(
    int year,
    int month,
    int day
)
DateTime コンストラクター (Int32, Int32, Int32) (System) | MSDN
public DateTime(
    int year,          // 年
    int month,         // 月
    int day,           // 日
    int hour,          // 時
    int minute,        // 分
    int second,        // 秒
    int millisecond,   // ミリ秒
    Calendar calendar, // 暦
    DateTimeKind kind  // 現地時刻、世界協定時刻 (UTC) またはそれ以外
)
DateTime コンストラクター (Int32, Int32, Int32, Int32, Int32, Int32, Int32, Calendar, DateTimeKind) (System) | MSDN
public DateTime(
    long ticks // タイマー刻みの時間
)
DateTime コンストラクター (Int64) (System) | MSDN
new DateTime(0);        // "0001/01/01 0:00:00"
new DateTime(10000000); // "0001/01/01 0:00:01"

コンストラクタ以外にも、DateTimeを生成する静的メソッドが多数用意されています。

プロパティ

静的プロパティ
プロパティ 内容
DateTime Now コンピューター上の現在の日時 (現地時刻)

その解像度はシステムタイマーに依存するため、連続して呼び出すと同じ値が返ることがある

DateTime UtcNow コンピューター上の現在の日時 (世界協定時刻 (UTC))
DateTime Today コンピューター上の現在の日付 (現地時刻)。時刻部分は00:00:00
プロパティ 内容
int Year 年の部分
int Month 月の部分
int Day 日の部分
DateTime Date 日付の部分
int Hour 時間の部分
int Minute 分の部分
int Second 秒の部分
int Millisecond ミリ秒の部分
long Ticks 日付と時刻を表すタイマー刻みの時間

0001/01/01 00:00:00.000を基準とした100ナノ秒単位の経過時間。1秒あたりの値は、TimeSpan.TicksPerSecondから得れる

new DateTime(1,1,1,0,0,0).Ticks; // 0
new DateTime(1,1,1,0,0,1).Ticks; // 10000000

なおWindowsファイル時刻はこれとは異なり、起点を1601/01/01としています。

int DayOfYear 年間積算日
DayOfWeek DayOfWeek 曜日
TimeSpan TimeOfDay 時刻
DateTimeKind Kind 時刻の種類 (現地時刻、世界協定時刻 (UTC)、またはそのどちらでもない)
プロパティ - DateTime 構造体 (System) | MSDN

Kind

DateTime dateTime1 = new DateTime(1, 2, 3, 4, 5, 6, 7, DateTimeKind.Unspecified);
DateTime dateTime2 = new DateTime(1, 2, 3, 4, 5, 6, 7, DateTimeKind.Local);
DateTime dateTime3 = new DateTime(1, 2, 3, 4, 5, 6, 7, DateTimeKind.Utc);

dateTime1.ToString("o"); // "0001-02-03T04:05:06.0070000"
dateTime2.ToString("o"); // "0001-02-03T04:05:06.0070000+09:00"
dateTime3.ToString("o"); // "0001-02-03T04:05:06.0070000Z"

メソッド

メソッド 機能
ToUniversalTime() 世界協定時刻 (UTC) に変換できる
ToLocalTime() 現地時刻に変換できる
   
DateTimeを生成するメソッド
メソッド 変換元 解析方法 解析の失敗
Parse(String) 日付と時刻の文字列形式 一般的な形式 FormatExceptionが投げられる
TryParse(String, DateTime) 日付と時刻の文字列形式 一般的な形式 falseが返される
ParseExact(String, String, IFormatProvider) 日付と時刻の文字列形式 指定の形式 FormatExceptionが投げられる
TryParseExact(String, String, IFormatProvider, DateTimeStyles, DateTime) 日付と時刻の文字列形式 指定の形式 falseが返される
FromFileTime(Int64) Windowsファイル時刻 タイマー刻みの現地時刻  
FromFileTimeUtc(Int64) Windowsファイル時刻 タイマー刻みのUTC時刻  
FromOADate(Double) OLEオートメーション日付    
FromBinary(Int64) 64ビットのバイナリ値    
メソッド - DateTime 構造体 (System) | MSDN
DateTime.FromFileTime(0);    // "1601/01/01 9:00:00"
DateTime.FromFileTimeUtc(0); // "1601/01/01 0:00:00"
タイマー刻みの時間との相互変換
DateTime dateTime1 = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Local);
long ticks = dateTime1.Ticks; // 631139040000000000

DateTime dateTime2 = new DateTime(ticks);                   // "2001/01/01 0:00:00"
DateTime dateTime3 = new DateTime(ticks, DateTimeKind.Utc); // "2001/01/01 0:00:00"
Windowsファイル時刻との相互変換
DateTime dateTime1 = new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Local);
long fileTime    = dateTime1.ToFileTime();    // 126227484000000000
long fileTimeUtc = dateTime1.ToFileTimeUtc(); // 126227484000000000

DateTime dateTime2 = DateTime.FromFileTime(fileTime);    // "2001/01/01 0:00:00"
DateTime dateTime3 = DateTime.FromFileTimeUtc(fileTime); // "2000/12/31 15:00:00"

Parse()

文字列形式の日付から、DateTimeを生成できます。

メソッド  
Parse(String) 現在のカルチャ
Parse(String, IFormatProvider) カルチャ固有の書式情報
Parse(String, IFormatProvider, DateTimeStyles) カルチャ固有の書式情報と書式スタイル
DateTime.Parse メソッド (System) | Microsoft Learn

書式情報とスタイルを省略した形式では、DateTimeFormatInfo.CurrentInfoとDateTimeStyles.Noneが指定されます。Parse - datetime.cs

string s = "01/02/2000 00:00";
DateTime d1 = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("ja-JP")); // 2000/01/02 0:00:00
DateTime d2 = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("en-US")); // 2000/01/02 0:00:00
DateTime d3 = DateTime.Parse(s, CultureInfo.CreateSpecificCulture("en-GB")); // 2000/02/01 0:00:00

bool r1 = d1 == d2; // true
bool r2 = d2 == d3; // false

演算子

==演算子では等しいことをTicksの値で判断され、Kindは考慮されません。Remarks - DateTime.Equality(DateTime, DateTime) Operator (System) | Microsoft Learn

内部的には100ナノ秒間隔のタイマー刻みの値を持つため、標準の文字列形式で等しくとも、オブジェクトの値が一致しないことがあります。DateTime 値と、それぞれの文字列表現 - DateTime 構造体 (System) | MSDN

DateTime dateTime1 = new DateTime(2001, 1, 1);             // {2001/01/01 0:00:00}
DateTime dateTime2 = new DateTime(2001, 1, 1, 0, 0, 0, 1); // {2001/01/01 0:00:00}

bool r1 = dateTime1.ToString() == dateTime2.ToString(); // true
bool r2 = dateTime1 == dateTime2;                       // false

// 1秒未満を切り捨てて比較
bool r3 = dateTime1.Ticks / TimeSpan.TicksPerSecond == dateTime2.Ticks / TimeSpan.TicksPerSecond; // true

加算、減算には同等のメソッドAdd()、Subtract()があります。

DateTime d1 = new DateTime(2000, 1, 1);
DateTime d2 = new DateTime(2000, 1, 3);

DateTime a1 = d1 + new TimeSpan(1, 0, 0, 0);    // 2000/01/02 0:00:00
DateTime a2 = d1.Add(new TimeSpan(1, 0, 0, 0)); // 2000/01/02 0:00:00

DateTime s1 = d1 - new TimeSpan(1, 0, 0, 0);         // 1999/12/31 0:00:00
DateTime s2 = d1.Subtract(new TimeSpan(1, 0, 0, 0)); // 1999/12/31 0:00:00

TimeSpan e1 = d2 - d1;         // 2.00:00:00
TimeSpan e2 = d1 - d2;         // -2.00:00:00
TimeSpan e3 = d2.Subtract(d1); // 2.00:00:00

文字列形式での取得

DateTime dateTime = new DateTime(1, 2, 3, 4, 5, 6, 7);
dateTime.ToLongDateString();  // "0001年2月3日"
dateTime.ToShortDateString(); // "0001/02/03"
dateTime.ToString();          // "0001/02/03 4:05:06"

dateTime.ToString(new DateTimeFormatInfo());                    // "02/03/0001 04:05:06"
dateTime.ToString(CultureInfo.InvariantCulture.DateTimeFormat); // "02/03/0001 04:05:06"

dateTime.ToString(new CultureInfo("en-US")); // "2/3/0001 4:05:06 AM"
dateTime.ToString(CultureInfo.CreateSpecificCulture("en-GB")); // "03/02/0001 04:05:06"

日時書式指定文字列

DateTime dateTime = new DateTime(1, 2, 3, 4, 5, 6, 7);
dateTime.ToString();    // "0001/02/03 4:05:06"
dateTime.ToString("d"); // "0001/02/03"
dateTime.ToString("D"); // "0001年2月3日"
dateTime.ToString("f"); // "0001年2月3日 4:05"
dateTime.ToString("F"); // "0001年2月3日 4:05:06"
dateTime.ToString("o"); // "0001-02-03T04:05:06.0070000" (ISO 8601準拠) "O"でも同じ

dateTime.ToString("yyyy/MM/dd HH:mm:ss.FFF"); // "0001/02/03 04:05:06.007"
メソッド 実装
ToShortDateString() DateTimeFormat.Format(this, "d", DateTimeFormatInfo.CurrentInfo); ToShortDateString - datetime.cs
ToLongDateString() DateTimeFormat.Format(this, "D", DateTimeFormatInfo.CurrentInfo);
   
書式指定子    
g または gg 年代、年号 A.D.
y  
M 1 ~ 12
MM 01 ~ 12
MMM 月の省略名  
MMMM 月の完全名  
d 日にち 1 ~ 31
dd 01 ~ 31
ddd 曜日の省略名 Mon
dddd 曜日の完全名 Monday
t AM/PM A、P、午
tt AM/PM AM、PM、午後
h 12時間形式の時間※1  
hh  
H 24時間形式の時間  
HH  
m  
mm  
s  
ss  
f 秒数の小数部  
F 秒数の小数部 0ならば何も表示されない
カスタム日時形式文字列 - .NET | Microsoft Learn ※1 TimeSpanでは"h"で24時間形式だが、DateTimeで同様にするには"H"とする必要がある
ファイル名への変換

"/"はファイル名に使用できないため、使用できる形式で取得するにはDateTime.Now.ToString("yyyyMMddHHmmssfff")のようにカスタム書式で取得するか、DateTime.Now.Ticks.ToString()のようにタイマー刻みの数を文字列に変換して用います。c# - Append TimeStamp to a File Name - Stack Overflow

参考
  • bear.mini : [.NET] DateTime.ToString() 書式指定文字列 まとめ

DateTimeOffset 構造体

DateTimeOffsetは日時と共にUTCとの差を保持しているため、つねに一点の時間を表します。 DateTimeOffset 構造体 - 日付と時刻に関連する型を比較する - .NET | Microsoft Learn DateTimeとDateTimeOffsetの違いとは?[C#、VB]:.NET TIPS - @IT 山本康彦 (2015/06/24)

TimeSpan 構造体

コンストラクタ

public TimeSpan(
    int days,        // 日数
    int hours,       // 時間数
    int minutes,     // 分数
    int seconds,     // 秒数
    int milliseconds // ミリ秒数
)
TimeSpan コンストラクター (Int32, Int32, Int32, Int32, Int32) (System) | MSDN TimeSpan コンストラクター (System) | MSDN
TimeSpan timeSpan = new TimeSpan(1, 2, 3);
timeSpan.ToString(); // "01:02:03"
new TimeSpan(100).ToString();        // "00:00:00.0000100"
new TimeSpan(1, 0, 0, 0).ToString(); // "1.00:00:00"

負数も許容されます。

new TimeSpan(-1, 10, 0).ToString(); // "-00:50:00"

パラメータを個別に指定する必要がないならば、TimeSpanを生成する静的メソッドから作成します。

プロパティ

静的プロパティ
プロパティ 内容
long TicksPerSecond タイマー刻みの数を1秒で表す 10000000
long TicksPerMillisecond タイマー刻みの数を1ミリ秒で表す 10000
       
プロパティ 内容
int Days 時間間隔の日数の部分
int Hours 時間間隔の時間の部分
int Milliseconds 時間間隔のミリ秒の部分
int Minutes 時間間隔の分の部分
int Seconds 時間間隔の秒の部分
double TotalDays 日数で表した時間間隔
double TotalHours 時間数で表した時間間隔
double TotalMinutes 分数で表した時間間隔
double TotalSeconds 秒数で表した時間間隔
double TotalMilliseconds ミリ秒数で表した時間間隔
long Ticks タイマー刻み (100ナノ秒間隔) で表した時間間隔
プロパティ - TimeSpan 構造体 (System) | MSDN
TimeSpan timeSpan = new TimeSpan(0, 0, 3600);
timeSpan.Hours;   // 1
timeSpan.Minutes; // 0
timeSpan.Seconds; // 0

timeSpan.TotalHours;   // 1
timeSpan.TotalMinutes; // 60
timeSpan.TotalSeconds; // 3600
TimeSpan timeSpan = new TimeSpan(0, 0, 0, 100, 500);
timeSpan.Minutes; // 1
timeSpan.Seconds; // 40

timeSpan.TotalMinutes; // 1.675
timeSpan.TotalSeconds; // 100.5

プロパティはすべて読み取り専用のため、時間を変更する必要があるときにはインスタンスを作成し直します。

これらのプロパティは、次のような計算値を返します。

メソッド

TimeSpanを生成するメソッド
メソッド 変換元
Parse(String) 時間間隔の文字列形式

秒単位で指定する場合、小数部は7桁まで

FromDays(Double) 日数
FromHours(Double) 時間数
TimeSpan.FromHours(25.5); // "1.01:30:00"
FromMinutes(Double) 分数
FromSeconds(Double) 秒数
TimeSpan.FromSeconds(100.5); // "00:01:40.5000000"
FromMilliseconds(Double) ミリ秒数
FromTicks(Int64) タイマー刻みの時間
メソッド - TimeSpan 構造体 (System) | MSDN

演算子

演算子 - TimeSpan 構造体 (System) | MSDN
TimeSpan timeSpan1 = new TimeSpan(0, 10, 30); // "00:10:30"
TimeSpan timeSpan2 = new TimeSpan(0, 20, 30); // "00:20:30"

TimeSpan timeSpan3 = timeSpan1 + timeSpan2;   // "00:31:00"

文字列形式での取得

時間書式指定文字列

一般の書式指定子とは異なる、独自の指定子が定義されています。

標準の書式指定子
書式指定子 名称 整形例
TimeSpan(1, 2, 3, 4, 5) TimeSpan(0, 1, 2, 3)
c 固定の書式指定子 "1.02:03:04.0050000" "01:02:03"
g 一般の短い書式 "1:2:03:04.005" "1:02:03"
G 一般の長い書式 "1:02:03:04.0050000" "0:01:02:03.0000000"
標準 TimeSpan 書式指定文字列 - .NET | Microsoft Learn

任意の書式とするには、下表の指定子を用います。これらはDaysプロパティのように時間間隔の特定の部分を表すものであり、TotalDaysプロパティのように時間間隔全体を意味しません。

書式指定子   範囲
d または %d 日数 0 ~ 31
dd ~ dddddddd 00 ~ 31 (文字と同数)
h または %h 時間数 0 ~ 23
hh 00 ~ 23
m または  %m 分数 0 ~ 59
mm 00 ~ 59
s または %s 秒数 0 ~ 59
ss 00 ~ 59
F ~ FFFFFFF 秒数の小数部 0 ~ 9999999 (0ならば何も表示されない)(文字と同数)
f ~ fffffff 0000000 ~ 9999999 (文字と同数)
カスタム TimeSpan 書式指定文字列 - .NET | Microsoft Learn

指定子以外の文字を書式指定文字列に含めるには、

  • リテラル文字列を、単一引用符 (') で囲む
  • リテラル文字を、バックスラッシュ (\) でエスケープする
    (バックスラッシュを記述するには「\\」とする必要があるため、@を付けて逐語的文字列とした方が可読性を高められる)

のいずれかの対処が必要です。その他の文字 - カスタム時間間隔書式指定文字列 | MSDN

new TimeSpan(0, 1, 2, 3, 4).ToString("hh':'mm':'ss'.'fff"); // "01:02:03.004"
new TimeSpan(0, 1, 2, 3, 4).ToString("hh\\:mm\\:ss\\.fff"); // "01:02:03.004"

new TimeSpan(0, 1, 2, 3, 4).ToString(@"hh\:mm\:ss\.fff");   // "01:02:03.004"
new TimeSpan(5, 1, 2, 3, 4).ToString(@"hh\:mm\:ss\.fff");   // "01:02:03.004"
new TimeSpan(1, 2, 3).ToString("%m' minutes'");               // "2 minutes"
new TimeSpan(1, 2, 3).ToString("%m\\ \\m\\i\\n\\u\\t\\e\\s"); // "2 minutes"

負号

標準の書式指定子ならば、値が負ならば自動で負号がつきます。

TimeSpan.FromSeconds(10).ToString("g");  // "00:00:10"
TimeSpan.FromSeconds(-10).ToString("g"); // "-00:00:10"

しかしカスタム書式指定子には負号を表現する指定子がないため、独自に実装する必要があります。.net - Formatting a negative TimeSpan - Stack Overflow

カスタム TimeSpan 書式指定子には、負と正の時間間隔の区別に使用できる符号も含まれていません。 符号を含めるには、条件ロジックを使用して書式指定文字列を構成する必要があります。

カスタム時間間隔書式指定文字列 | MSDN
TimeSpan timeSpan = TimeSpan.FromSeconds(-10);
timeSpan.ToString((timeSpan < TimeSpan.Zero ? "\\-" : "") + @"hh\:mm\:ss"); // "-00:00:10"

これは補間文字列を用いると、次のようにも記述できます。

timeSpan.ToString($@"{(timeSpan < TimeSpan.Zero ? "\\-" : "")}hh\:mm\:ss"); // "-00:00:10"

Calendar クラス

  • System.Object
    • System.Globalization.Calendar
      • System.Globalization.EastAsianLunisolarCalendar
      • System.Globalization.GregorianCalendar
      • System.Globalization.HebrewCalendar
      • System.Globalization.HijriCalendar
      • System.Globalization.JapaneseCalendar
      • System.Globalization.JulianCalendar
      • System.Globalization.KoreanCalendar
      • System.Globalization.PersianCalendar
      • System.Globalization.TaiwanCalendar
      • System.Globalization.ThaiBuddhistCalendar
      • System.Globalization.UmAlQuraCalendar

Stopwatch

処理時間を計測するには、次のようにします。

Stopwatch stopwatch = Stopwatch.StartNew();

// 時間のかかる処理

stopwatch.Stop();
Console.Write( stopwatch.ElapsedMilliseconds );

プロパティの値は、動作状況に応じて次のように変化します。

Stopwatch stopwatch = new Stopwatch();
Console.Write(stopwatch.ElapsedMilliseconds); // 0
Console.Write(stopwatch.IsRunning);           // False

stopwatch.Start();
Task.Delay(100).Wait();

Console.Write(stopwatch.ElapsedMilliseconds); // 110
Console.Write(stopwatch.IsRunning);           // True

stopwatch.Stop();
Task.Delay(200).Wait();

Console.Write(stopwatch.ElapsedMilliseconds); // 110
Console.Write(stopwatch.IsRunning);           // False

stopwatch.Restart();
Task.Delay(300).Wait();

Console.Write(stopwatch.ElapsedMilliseconds); // 310
Console.Write(stopwatch.IsRunning);           // True

Stopwatchでの時間は、高解像度のパフォーマンス カウンターがサポートされている (IsHighResolutionがtrue) ならばQueryPerformanceCounter()で、さもなくばDateTime.UtcNow.Ticksの値に基づいて計測されます。GetTimestamp - GetTimestamp

プロパティ

プロパティ  
TimeSpan Elapsed 経過時間の合計
long ElapsedMilliseconds 経過時間の合計 (ミリ秒単位)
long ElapsedTicks 経過時間の合計 (タイマー刻み)
bool IsRunning trueならば、タイマーが実行中
  • true … Start()などの呼び出しで計測が開始されている
  • false … Start()などの呼び出し前か、Stop()などで計測が停止されている
Properties - Stopwatch Class (System.Diagnostics) | Microsoft Learn

Elapsed

Elapsed - Stopwatch.cs

ElapsedTicks

ElapsedTicksプロパティが返すタイマー刻みの値は、Stopwatch.Frequencyの分解能となります。その値はハードウェアやOSに依存するため、1/10,000,000秒の分解能 (TimeSpan.TicksPerSecond) であるTimeSpanのタイマー刻みとは異なります。そのためTimeSpan.FromTicks(stopwatch.ElapsedTicks)とStopwatch.Elapsedは異なる時間となることがあります。

メソッド

メソッド 機能
StartNew() インスタンスを作成し、計測を開始する
Start() 計測を開始する
Stop() 計測を停止する
Reset() 計測を停止し、経過時間をゼロにリセットする。
Restart() 計測を停止し、経過時間をゼロにリセットする。そして計測を開始する
Methods - Stopwatch Class (System.Diagnostics) | Microsoft Learn

Stop()

Stop()は経過時間が変化しないように計測を一時停止するだけであり、リソースを解放するようなものではありません。 Stop - Stopwatch.cs Remarks - Stopwatch.Stop Method (System.Diagnostics) | Microsoft Learn c# - Should I Stop Stopwatch at the end of the method? - Stack Overflow

参考

参考書

Microsoft Learnから検索