ここでは、「1992/2/16 12:15:12」のように日時を表す文字列をDateTimeオブジェクトに変換する方法を説明します。
DateTimeだけでなく、DateTimeOffsetへの変換に関する説明も一部含まれています。
単純な変換であれば、DateTime.Parseメソッドで簡単に出来ます。説明も不要と思いますので、具体例をご覧ください。
'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 '日付を省略すると、現在の日付となる
//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値に変換する例を示します。
'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)
//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値に簡単に変換できます。
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)
//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秒)ですので、それ以前の時刻は変換できません。
変換元の文字列が独特の書式であったり、書式が不確定で多数の候補を考慮しなければならないなどのケースでは、DateTime.ParseExactメソッドを使用します。
ParseExactメソッドでは書式の定義を、カスタム日時書式指定文字列で行います。カスタム日時書式指定文字列については、「日時(DateTimeオブジェクト)を文字列に変換する」で説明しています。
以下に例を示します。変換する文字列の書式が一つに決まっている場合と、可能性のある書式が複数ある場合の2つの例を紹介しています。
'"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"と表示される
//"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で変換できなかった場合は、例外がスローされます。例外をスローさせずにDateTimeに変換できるかを確かめるには、DateTime.TryParseやTryParseExactメソッドを使います。これらについて詳しくは、「文字列が日付型(DateTime)に変換できるか調べる」で説明します。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。