VBのIsDate関数を使えば、指定した文字列が日付値(DateTime値)に変換できるか調べることができます。ここでは、VB.NETのMicrosoft.VisualBasic.Information.IsDateメソッドを使うことなく、指定した文字列がDateTime値に変換できるか調べる方法を紹介します。
IsDateの代わりになりそうな方法には、「文字列が数値に変換できるか調べる」で紹介している方法と同様に、以下のような方法が考えられます。
ここでは1と2の方法を紹介します。3の方法については、ごく簡単にだけ説明します。
この方法は.NET Framework 2.0以降でしか使えませんが、通常最も良い方法です。DateTime.TryParseメソッドを使えば、DateTime.Parseメソッドで文字列をDateTime値に変換できるかを調べることができます。調べるだけでなく、変換できるならばその値を取得することもできます。
以下にDateTime.TryParseメソッドを使った簡単な例を示します。
Dim str As String = "2000/1/1" 'DateTimeに変換できるか確かめる Dim dt As DateTime If DateTime.TryParse(str, dt) Then '変換出来たら、dtにその値が入る Console.WriteLine("{0}はDateTime{1}に変換できます。", str, dt) Else Console.WriteLine("{0}はDateTimeに変換できません。", str) End If
string str = "2000/1/1"; //DateTimeに変換できるか確かめる DateTime dt; if (DateTime.TryParse(str, out dt)) { //変換出来たら、dtにその値が入る Console.WriteLine("{0}はDateTime{1}に変換できます。", str, dt); } else { Console.WriteLine("{0}はDateTimeに変換できません。", str); }
TryParseメソッドには、Parseメソッド同様、カルチャとDateTimeStylesを指定することもできます。これらについて詳しくは、「日時を表す文字列をDateTimeオブジェクトに変換する」で説明しています。
文字列がDateTime.ParseExactメソッドでDateTime値に変換できるかを調べるには、DateTime.TryParseExactメソッドを使います。DateTime.ParseExactメソッドに関しても詳しくは、「日時を表す文字列をDateTimeオブジェクトに変換する」をご覧ください。
もしDateTime.TryParseメソッドが使えるならばその方がいいですが、.NET Framework 1.1以前などのようにDateTime.TryParseメソッドが使えない場合は、この方法になります。
なお、DateTime.Parseメソッドについては「日時を表す文字列をDateTimeオブジェクトに変換する」で、例外処理については「エラー処理(例外処理)の基本」で説明しています。
以下に、指定した文字列をDateTimeの値に変換できるか調べるメソッドの例を示します。
''' <summary> ''' 指定した文字列をDateTimeの値に変換できるか調べます。 ''' </summary> ''' <param name="s">文字列。</param> ''' <returns>s をDateTimeの値に変換できる場合は true。 ''' それ以外は false。</returns> Public Shared Function TryParseToDateTime(ByVal s As String) As Boolean Try DateTime.Parse(s) Catch ex As StackOverflowException Throw Catch ex As OutOfMemoryException Throw Catch ex As System.Threading.ThreadAbortException Throw Catch Return False End Try Return True End Function
/// <summary> /// 指定した文字列をDateTimeの値に変換できるか調べます。 /// </summary> /// <param name="s">文字列。</param> /// <returns>s をDateTimeの値に変換できる場合は true。 /// それ以外は false。</returns> public static bool TryParseToDateTime(string s) { try { DateTime.Parse(s); } catch (StackOverflowException) { throw; } catch (OutOfMemoryException) { throw; } catch (System.Threading.ThreadAbortException) { throw; } catch { return false; } return true; }
正規表現だけを使って文字列がDateTimeに変換できるか調べるのは、不可能に近いでしょう。しかし、指定された文字列が日時の書式に合っているかを調べるだけならば、大変役に立ちます。
以下に、正規表現を使って文字列が日付っぽいか、時刻っぽいか、日時っぽいか調べる例を示します。
ここでは、日付を調べる正規表現パターンを、「^(?<year>[0-9]{4}|[0-9]{2})(?<datesep>\/|-|\.)(?<month>0?[1-9]|1[012])\k<datesep>(?<day>0?[1-9]|[12][0-9]|3[01])$」としてみました。年月日を区切る記号は、"/", "-", "." のいずれでも可能としました。年は4桁と2桁のどちらでも可能としました。一桁の月や日は、先頭に 0 があってもなくてもいいようにしました。月と日の関係は考慮していませんので、「2000/2/31」のようにあり得ない日付でも一致してしまいます。
時刻を調べる正規表現パターンは、「^(?<hour>0?[0-9]|1[0-9]|2[0-3])(?<timesep>:)(?<minute>0?[0-9]|[1-5][0-9])(?:\k<timesep>(?<second>0?[0-9]|[1-5][0-9]))?$」としました。時刻は、24時間制表示です。一桁の時分秒は、先頭に 0 があってもなくてもいいようにしました。秒は省略できます。
日時を調べる正規表現パターンは、上の2つを足したものです。ただ、日付と時刻のどちらかだけでもよいようにしました。日付と時刻を区切りは、スペース文字1個です。
Dim s As String = "1992/02/16 12:15:12" '文字列が日付の書式に合っているか調べる If System.Text.RegularExpressions.Regex.IsMatch(s, _ "^(?<year>[0-9]{4}|[0-9]{2})(?<datesep>\/|-|\.)" & _ "(?<month>0?[1-9]|1[012])\k<datesep>" & _ "(?<day>0?[1-9]|[12][0-9]|3[01])$") Then Console.WriteLine("日付パターンにマッチしました") End If '文字列が時刻の書式に合っているか調べる If System.Text.RegularExpressions.Regex.IsMatch(s, _ "^(?<hour>0?[0-9]|1[0-9]|2[0-3])(?<timesep>:)" & _ "(?<minute>0?[0-9]|[1-5][0-9])" & _ "(?:\k<timesep>(?<second>0?[0-9]|[1-5][0-9]))?$") Then Console.WriteLine("時刻パターンにマッチしました") End If '文字列が日時の書式に合っているか調べる If System.Text.RegularExpressions.Regex.IsMatch(s, _ "^((?<year>[0-9]{4}|[0-9]{2})(?<datesep>\/|-|\.)" & _ "(?<month>0?[1-9]|1[012])\k<datesep>" & _ "(?<day>0?[1-9]|[12][0-9]|3[01])( |$))?" & _ "((?<hour>0?[0-9]|1[0-9]|2[0-3])(?<timesep>:)" & _ "(?<minute>0?[0-9]|[1-5][0-9])" & _ "(?:\k<timesep>(?<second>0?[0-9]|[1-5][0-9]))?)?$") Then Console.WriteLine("日時パターンにマッチしました") End If
string s = "1992/02/16 12:15:12"; //文字列が日付の書式に合っているか調べる if (System.Text.RegularExpressions.Regex.IsMatch(s, @"^(?<year>[0-9]{4}|[0-9]{2})(?<datesep>\/|-|\.)" + @"(?<month>0?[1-9]|1[012])\k<datesep>" + @"(?<day>0?[1-9]|[12][0-9]|3[01])$")) { Console.WriteLine("日付パターンにマッチしました"); } //文字列が時刻の書式に合っているか調べる if (System.Text.RegularExpressions.Regex.IsMatch(s, @"^(?<hour>0?[1-9]|1[012])(?<timesep>:)" + @"(?<minute>0?[1-9]|[1-5][0-9])" + @"(?:\k<timesep>(?<second>0?[1-9]|[1-5][0-9]))?$")) { Console.WriteLine("時刻パターンにマッチしました"); } //文字列が日時の書式に合っているか調べる if (System.Text.RegularExpressions.Regex.IsMatch(s, @"^((?<year>[0-9]{4}|[0-9]{2})(?<datesep>\/|-|\.)" + @"(?<month>0?[1-9]|1[012])\k<datesep>" + @"(?<day>0?[1-9]|[12][0-9]|3[01])( |$))?" + @"((?<hour>0?[0-9]|1[0-9]|2[0-3])(?<timesep>:)" + @"(?<minute>0?[0-9]|[1-5][0-9])" + @"(?:\k<timesep>(?<second>0?[0-9]|[1-5][0-9]))?)?$")) { Console.WriteLine("日時パターンにマッチしました"); }
私の書いたパターンよりもきっとより良いものが「Regular Expression Library」にあると思いますので、探してみてください。
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。