DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

日時を表す文字列をDateTimeオブジェクトに変換する

ここでは、「1992/2/16 12:15:12」のように日時を表す文字列をDateTimeオブジェクトに変換する方法を説明します。

DateTimeだけでなく、DateTimeOffsetへの変換に関する説明も一部含まれています。

Parseメソッドで変換する

単純な変換であれば、DateTime.Parseメソッドで簡単に出来ます。説明も不要と思いますので、具体例をご覧ください。

VB.NET
コードを隠すコードを選択
'DateTime値に変換する文字列
Dim s1 As String = "1992/2/16 12:15:12"
'文字列をDateTime値に変換する
Dim dt1 As DateTime = DateTime.Parse(s1)
'結果を表示する
Console.WriteLine(dt1)
'1992/02/16 12:15:12

'時間が省略されている
Dim s2 As String = "1992/2/16"
Dim dt2 As DateTime = DateTime.Parse(s2)
Console.WriteLine(dt2)
'1992/02/16 0:00:00
'時間を省略すると、「0:00:00」となる

'日付が省略されている
Dim s3 As String = "12:15:12"
Dim dt3 As DateTime = DateTime.Parse(s3)
Console.WriteLine(dt3)
'2003/03/12 12:15:12
'日付を省略すると、現在の日付となる
C#
コードを隠すコードを選択
//DateTime値に変換する文字列
string s1 = "1992/2/16 12:15:12";
//文字列をDateTime値に変換する
DateTime dt1 = DateTime.Parse(s1);
//結果を表示する
Console.WriteLine(dt1);
//1992/02/16 12:15:12

//時間が省略されている
string s2 = "1992/2/16";
DateTime dt2 = DateTime.Parse(s2);
Console.WriteLine(dt2);
//1992/02/16 0:00:00
//時間を省略すると、「0:00:00」となる

//日付が省略されている
string s3 = "12:15:12";
DateTime dt3 = DateTime.Parse(s3);
Console.WriteLine(dt3);
//2003/03/12 12:15:12
//日付を省略すると、現在の日付となる
補足:.NET Framework 2.0以降では、上記コードで作成されたDateTimeオブジェクトのKindプロパティはUnspecifiedになります。

カルチャを指定して変換する

上記の方法では、現在のカルチャを使用して変換を行います。もし特定のカルチャに独特の書式(フォーマット)で書かれた文字列をDateTime値に変換するならば、変換に使用するカルチャを2番目のパラメータに指定できます。このパラメータの型はIFormatProviderですが、通常ここにはCultureInfoかDateTimeFormatInfoオブジェクトを指定します。

2番目のパラメータにIFormatProviderを指定したときは、3番目のパラメータにDateTimeStyles列挙体も指定します。これによって、世界協定時刻(UTC)に変換するかや、空白文字を無視するか、文字列に日付が含まれていないときにグレゴリオ暦の1年1月1日にするかなどを指定できます。

DateTimeStyles列挙体の値には、以下のようなものがあります(説明は、MSDNからの抜粋です)。なお説明の中にある「DateTimeFormatInfo」というのは、2番目のパラメータに指定したDateTimeFormatInfoオブジェクト(または、CultureInfoオブジェクトのDateTimeFormatプロパティ)のことです。

メンバ名 説明 補足
None 既定の形式指定オプションを使用します。この値は、 Parse 、 ParseExact 、および TryParse の既定のスタイルを表します。 文字列に日付情報が含まれていない場合、返されるDateTimeの日付は1年1月1日になる。
文字列にタイムゾーン情報が含まれていない場合、返されるDateTimeのKindプロパティDateTimeKind.Unspecifiedになる。タイムゾーン情報が含まれている場合、時刻が現地時刻に変換され、返されるDateTimeのKindプロパティはDateTimeKind.Localになる。
DateTime.ParseとTryParseでは、この値を指定しても空白は無視される。
ParseExactでは、書式指定子にない余計な空白は許可されない。
AllowLeadingWhite DateTimeFormatInfo 形式パターンに従っている場合を除き、解析中に先行する空白文字を無視します。 ParseとTryParseでは文字列内に空白文字を使用できるため、この値は無視される。
AllowTrailingWhite DateTimeFormatInfo 形式パターンに従っている場合を除き、解析中に末尾の空白文字を無視します。 ParseとTryParseでは文字列内に空白文字を使用できるため、この値は無視される。
AllowInnerWhite DateTimeFormatInfo 形式パターンに従っている場合を除き、解析中に文字列の中間部分に存在する空白文字を無視します。 ParseとTryParseでは文字列内に空白文字を使用できるため、この値は無視される。
AllowWhiteSpaces DateTimeFormatInfo 形式パターンに従っている場合を除き、解析中に文字列に含まれている空白文字を無視します。 この値は、 AllowLeadingWhite、 AllowTrailingWhite、 AllowInnerWhite の各値の組み合わせです。 ParseとTryParseでは文字列内に空白文字を使用できるため、この値は無視される。(常にこの値を使用しているのと同じになる。)
NoCurrentDateDefault 解析した文字列に含まれているのが時刻のみで日付がない場合、解析を行うメソッドは、年 = 1、月 = 1、および日 = 1 のグレゴリオ暦の日付であると想定します(つまり日付がDateTime.Date.MinValueの値となる)。この値を使用しない場合は、現在の日付が想定されます。 DateTimeOffsetでは使用できず、ArgumentExceptionがスローされる。
AdjustToUniversal 日付と時刻を世界協定時刻 (UTC) として返します。入力文字列に現地時刻が指定されている場合 (タイム ゾーン指定子または AssumeLocal を使用)、日付と時刻は現地時刻から UTC に変換されます。 入力文字列に UTC 時刻が指定されている場合 (タイム ゾーン指定子または AssumeUniversal を使用)、変換は実行されません。 入力文字列に現地時刻も UTC 時刻も指定されていない場合、変換は実行されず、結果の Kind プロパティは Unspecified になります。RoundTripKind で使用することはできません。 文字列を変換後、ToUniversalTimeメソッドを呼び出したのと同じになるが、この値を使って変換したほうが効率的。
AssumeLocal 解析対象文字列にタイム ゾーン指定がない場合、その文字列は現地時間を示していると見なされます。AssumeUniversal または RoundtripKind で使用することはできません。 DateTime.KindプロパティがDateTimeKind.Localになる。
DateTimeOffsetの場合は、オフセットがローカルタイムゾーンのオフセットになる。
AssumeUniversal 解析対象文字列にタイム ゾーン指定がない場合、その文字列は UTC を示していると見なされます。AssumeLocal または RoundtripKind で使用することはできません。 UTCから現地時間に変換され、DateTime.KindプロパティがDateTimeKind.Localになる。
DateTimeOffsetの場合は、オフセットが 00:00 になる。
RoundtripKind 日付の DateTimeKind フィールド(DateTime.Kind プロパティの事か?)は、 DateTime オブジェクトが標準の書式指定子文字列である o または r を使用して文字列に変換され、その文字列が DateTime オブジェクトに戻されても保持されます。 書式指定文字列に"o"、"r"、"u"(詳しくは、「日時(DateTimeオブジェクト)を文字列に変換する」)を指定してDateTimeオブジェクトを文字列に変換したとしても、その文字列をDateTime.ParseメソッドでDateTimeオブジェクトに戻すと、DateTime.KindプロパティがDateTimeKind.Localになり、時刻が現地時刻に変換されてしまう。このフラグはそうなることを防ぎ、KindプロパティがDateTimeKind.Utcになるようにする。
DateTimeOffsetには影響しない。

以下に、ja-JPカルチャで、現地時間として、文字列をDateTime値に変換する例を示します。

VB.NET
コードを隠すコードを選択
'DateTime値に変換する文字列
Dim s1 As String = "1992年2月16日 12時15分12秒"

'ja-JPカルチャで、現地時間として、文字列をDateTime値に変換する
Dim ci As New System.Globalization.CultureInfo("ja-JP")
Dim dt1 As DateTime = DateTime.Parse(s1, ci, _
    System.Globalization.DateTimeStyles.AssumeLocal)

'結果を表示する
Console.WriteLine("{0} ({1})", dt1, dt1.Kind)
'1992/02/16 12:15:12 (Local)
C#
コードを隠すコードを選択
//DateTime値に変換する文字列
string s1 = "1992年2月16日 12時15分12秒";

//ja-JPカルチャで、現地時間として、文字列をDateTime値に変換する
System.Globalization.CultureInfo ci =
    new System.Globalization.CultureInfo("ja-JP");
DateTime dt1 = DateTime.Parse(s1, ci,
    System.Globalization.DateTimeStyles.AssumeLocal);

//結果を表示する
Console.WriteLine("{0} ({1})", dt1, dt1.Kind);
//1992/02/16 12:15:12 (Local)

和暦の文字列を変換する

ja-JPカルチャを使用すれば、和暦の文字列もDateTime値に簡単に変換できます。

VB.NET
コードを隠すコードを選択
Dim dt As New DateTime(2000, 5, 12, 20, 30, 15, 123)

'ja-JPカルチャで、現地時間として、文字列をDateTime値に変換する
Dim ci As New System.Globalization.CultureInfo("ja-JP")

'和暦を変換する
Dim dt1 As DateTime = DateTime.Parse("平成4年2月16日 12時15分12秒", ci, _
    System.Globalization.DateTimeStyles.AssumeLocal)

'年号(元号)が省略された1文字(明, 大, 昭, 平)やアルファベット(M, T, S, H)でもOK
Dim dt2 As DateTime = DateTime.Parse("H4年2月16日 12時15分12秒", ci, _
    System.Globalization.DateTimeStyles.AssumeLocal)
C#
コードを隠すコードを選択
//ja-JPカルチャで、現地時間として、文字列をDateTime値に変換する
System.Globalization.CultureInfo ci =
    new System.Globalization.CultureInfo("ja-JP");

//和暦を変換する
DateTime dt1 = DateTime.Parse("平成4年2月16日 12時15分12秒", ci,
    System.Globalization.DateTimeStyles.AssumeLocal);

//年号(元号)が省略された1文字(明, 大, 昭, 平)やアルファベット(M, T, S, H)でもOK
DateTime dt2 = DateTime.Parse("H4年2月16日 12時15分12秒", ci,
    System.Globalization.DateTimeStyles.AssumeLocal);

和暦の変換はJapaneseCalendarを使って行われますが、JapaneseCalendarがサポートしている最も古い時刻は「1868/09/08 0:00:00」(明治1年9月8日 0時0分0秒)ですので、それ以前の時刻は変換できません。

Parseメソッドで変換できない書式の文字列をParseExactメソッドで変換する

変換元の文字列が独特の書式であったり、書式が不確定で多数の候補を考慮しなければならないなどのケースでは、DateTime.ParseExactメソッドを使用します。

ParseExactメソッドでは書式の定義を、カスタム日時書式指定文字列で行います。カスタム日時書式指定文字列については、「日時(DateTimeオブジェクト)を文字列に変換する」で説明しています。

以下に例を示します。変換する文字列の書式が一つに決まっている場合と、可能性のある書式が複数ある場合の2つの例を紹介しています。

VB.NET
コードを隠すコードを選択
'"Wed, 25 Dec 2002 13:32:22 +0900"をDateTime型に変更する
Dim str As String = "Wed, 25 Dec 2002 13:32:22 +0900"

'文字列の書式が一つに決まっている時
'ここでは"ddd, d MMM yyyy HH':'mm':'ss zzz"
Dim dt1 As DateTime = DateTime.ParseExact(str, _
                "ddd, d MMM yyyy HH':'mm':'ss zzz", _
                System.Globalization.DateTimeFormatInfo.InvariantInfo, _
                System.Globalization.DateTimeStyles.None)
Console.WriteLine(dt1)
'"2002/12/25 13:32:22"と表示される

'文字列の書式に複数の可能性がある時
'"ddd, d MMM yyyy HH':'mm':'ss zzz"の他にも"r"も考慮する
'dateTimeStringが"Wed, 25 Dec 2002 13:32:22 GMT"などでも変換されるようになる
Dim expectedFormats As String() = {"ddd, d MMM yyyy HH':'mm':'ss zzz", "r"}
Dim dt2 As DateTime = DateTime.ParseExact(str, _
                expectedFormats, _
                System.Globalization.DateTimeFormatInfo.InvariantInfo, _
                System.Globalization.DateTimeStyles.None)
Console.WriteLine(dt2)
'"2002/12/25 13:32:22"と表示される
C#
コードを隠すコードを選択
//"Wed, 25 Dec 2002 13:32:22 +0900"をDateTime型に変更する
string str = "Wed, 25 Dec 2002 13:32:22 +0900";

//文字列の書式が一つに決まっている時
//ここでは"ddd, d MMM yyyy HH':'mm':'ss zzz"
DateTime dt1 = System.DateTime.ParseExact(str,
            "ddd, d MMM yyyy HH':'mm':'ss zzz",
            System.Globalization.DateTimeFormatInfo.InvariantInfo,
            System.Globalization.DateTimeStyles.None);
Console.WriteLine(dt1);
//"2002/12/25 13:32:22"と表示される

//文字列の書式に複数の可能性がある時
//"ddd, d MMM yyyy HH':'mm':'ss zzz"の他にも"r"も考慮する
//dateTimeStringが"Wed, 25 Dec 2002 13:32:22 GMT"などでも変換されるようになる
string[] expectedFormats = { "ddd, d MMM yyyy HH':'mm':'ss zzz", "r" };
DateTime dt2 = System.DateTime.ParseExact(str,
            expectedFormats,
            System.Globalization.DateTimeFormatInfo.InvariantInfo,
            System.Globalization.DateTimeStyles.None);
Console.WriteLine(dt2);
//"2002/12/25 13:32:22"と表示される

ParseやParseExactで変換できるか試してみる

指定した文字列がParseやParseExactで変換できなかった場合は、例外がスローされます。例外をスローさせずにDateTimeに変換できるかを確かめるには、DateTime.TryParseやTryParseExactメソッドを使います。これらについて詳しくは、「文字列が日付型(DateTime)に変換できるか調べる」で説明します。

  • 履歴:
  • 2011/7/13 「カルチャを指定して変換する」を追加。その他書きなおし。
  • 2011/10/31 和暦を変換する例を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。