文字列が日付型(DateTime)に変換できるか調べる
C#でIsDateに代わるものは?
VBのIsDate関数 を使えば、指定した文字列が日付値(DateTime値)に変換できるか調べることができます。ここでは、VB.NETのMicrosoft.VisualBasic.Information.IsDateメソッドを使うことなく、指定した文字列がDateTime値に変換できるか調べる方法を紹介します。
IsDateの代わりになりそうな方法には、「文字列が数値に変換できるか調べる 」で紹介している方法と同様に、以下のような方法が考えられます。
DateTime.TryParseメソッドを使う。
DateTime.Parseメソッドで変換してみて例外が発生するか調べる。
正規表現で調べてみる。
一つ一つの文字を調べていき、適切かどうか確かめる。
ここでは1と2の方法を紹介します。3の方法については、ごく簡単にだけ説明します。
DateTime.TryParseメソッドを使う方法
この方法は.NET Framework 2.0以降でしか使えませんが、通常最も良い方法です。DateTime.TryParseメソッド を使えば、DateTime.Parseメソッドで文字列をDateTime値に変換できるかを調べることができます。調べるだけでなく、変換できるならばその値を取得することもできます。
以下にDateTime.TryParseメソッドを使った簡単な例を示します。
Dim str As String = "2000/1/1"
Dim dt As DateTime
If DateTime.TryParse(str, dt) Then
Console.WriteLine("{0}はDateTime{1}に変換できます。", str, dt)
Else
Console.WriteLine("{0}はDateTimeに変換できません。", str)
End If
string str = "2000/1/1";
DateTime dt;
if (DateTime.TryParse(str, out 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.Parseメソッドで変換してみて例外が発生するか調べる方法
もしDateTime.TryParseメソッドが使えるならばその方がいいですが、.NET Framework 1.1以前などのようにDateTime.TryParseメソッドが使えない場合は、この方法になります。
なお、DateTime.Parseメソッドについては「日時を表す文字列をDateTimeオブジェクトに変換する 」で、例外処理については「エラー処理(例外処理)の基本 」で説明しています。
以下に、指定した文字列をDateTimeの値に変換できるか調べるメソッドの例を示します。
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
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に変換できるか調べるのは、不可能に近いでしょう。しかし、指定された文字列が日時の書式に合っているかを調べるだけならば、大変役に立ちます。
以下に、正規表現を使って文字列が日付っぽいか、時刻っぽいか、日時っぽいか調べる例を示します。
ここでは、日付を調べる正規表現パターンを、「^(?[0-9]{4}|[0-9]{2})(?\/|-|\.)(?0?[1-9]|1[012])\k(?0?[1-9]|[12][0-9]|3[01])$」としてみました。年月日を区切る記号は、"/", "-", "." のいずれでも可能としました。年は4桁と2桁のどちらでも可能としました。一桁の月や日は、先頭に 0 があってもなくてもいいようにしました。月と日の関係は考慮していませんので、「2000/2/31」のようにあり得ない日付でも一致してしまいます。
時刻を調べる正規表現パターンは、「^(?0?[0-9]|1[0-9]|2[0-3])(?:)(?0?[0-9]|[1-5][0-9])(?:\k(?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?[1-9]|1[012])(?<timesep>:)" & _
"(?<minute>0?[1-9]|[1-5][0-9])" & _
"(?:\k<timesep>(?<second>0?[1-9]|[1-5][0-9]))?$") Then
Console.WriteLine("時刻パターンにマッチしました")
End If
If System.Text.RegularExpressions.Regex.IsMatch(s, _
"^(?=\d)((?<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?[1-9]|1[012])(?<timesep>:)" & _
"(?<minute>0?[1-9]|[1-5][0-9])(?:\k<timesep>" & _
"(?<second>0?[1-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,
@"^(?=\d)((?<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?[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("日時パターンにマッチしました");
}
私の書いたパターンよりもきっとより良いものが「Regular Expression Library 」にあると思いますので、探してみてください。
履歴:
2011/7/14 「正規表現を使う方法」を追加。その他、全体的な書き換え。