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

文字列が日付型(DateTime)に変換できるか調べる
C#でIsDateに代わるものは?

VBのIsDate関数を使えば、指定した文字列が日付値(DateTime値)に変換できるか調べることができます。ここでは、VB.NETのMicrosoft.VisualBasic.Information.IsDateメソッドを使うことなく、指定した文字列がDateTime値に変換できるか調べる方法を紹介します。

IsDateの代わりになりそうな方法には、「文字列が数値に変換できるか調べる」で紹介している方法と同様に、以下のような方法が考えられます。

  1. DateTime.TryParseメソッドを使う。
  2. DateTime.Parseメソッドで変換してみて例外が発生するか調べる。
  3. 正規表現で調べてみる。
  4. 一つ一つの文字を調べていき、適切かどうか確かめる。

ここでは1と2の方法を紹介します。3の方法については、ごく簡単にだけ説明します。

DateTime.TryParseメソッドを使う方法

この方法は.NET Framework 2.0以降でしか使えませんが、通常最も良い方法です。DateTime.TryParseメソッドを使えば、DateTime.Parseメソッドで文字列をDateTime値に変換できるかを調べることができます。調べるだけでなく、変換できるならばその値を取得することもできます。

以下にDateTime.TryParseメソッドを使った簡単な例を示します。

VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
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.Parseメソッドで変換してみて例外が発生するか調べる方法

もしDateTime.TryParseメソッドが使えるならばその方がいいですが、.NET Framework 1.1以前などのようにDateTime.TryParseメソッドが使えない場合は、この方法になります。

なお、DateTime.Parseメソッドについては「日時を表す文字列をDateTimeオブジェクトに変換する」で、例外処理については「エラー処理(例外処理)の基本」で説明しています。

以下に、指定した文字列をDateTimeの値に変換できるか調べるメソッドの例を示します。

VB.NET
コードを隠すコードを選択
''' <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
C#
コードを隠すコードを選択
/// <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個です。

VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
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」にあると思いますので、探してみてください。

  • 履歴:
  • 2011/7/14 「正規表現を使う方法」を追加。その他、全体的な書き換え。
  • 2016/9/4 「正規表現を使う方法」のコードで使用していたパターンが、説明文のパターンと違っていたのを修正。

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

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