web-dev-qa-db-ja.com

DateTime.MinValueおよびSqlDateTimeオーバーフロー

txtBirthDateを検証したくないので、DateTime.MinValueをデータベースに渡します。

私のコード:

 if (txtBirthDate.Text == string.Empty)
    objinfo.BirthDate = DateTime.MinValue;
 else
     objinfo.BirthDate =  DateTime.Parse(txtBirthDate.Text);

DateTime.MinValue return Date = {1/1/0001 12:00:00 AM}

SQLエラーが発生しました:

SqlDateTimeオーバーフロー。 1/1/1753 12:00:00 AMから12/31/9999 11:59:59 PMの間でなければなりません。

私はそれを理解していますが、DateTime.MinValueがデータベースに挿入できない無効な日付時刻を返す理由を理解していません。このタイプの状況を処理する方法は?

49
Shree

基本的に、DateTime.MinValueを使用して欠損値を表さないでください。 することはできません SQL ServerのDateTimeフィールドでDateTime.MinValueを使用します。SQLServerの開始値は1753年の最小値です。

代わりに、BirthDateプロパティをNullable<DateTime>(別名DateTime?)にし、値がない場合はnullに設定します。また、データベースフィールドがnull可能であることを確認してください。次に、そのnullがデータベース内でNULLの値になることを確認する必要があります。正確にどのように行うかは、データアクセスに依存しますが、データアクセスについては何も説明していません。

80
Jon Skeet

DateTime.MinValueを使用するのは非常に簡単です。代わりにSystem.Data.SqlTypes.SqlDateTime.MinValueを使用してください。

73
Sankar M

古い質問ですが、別の解決策は、データベース列にdatetime2を使用することです。 MSDNリンク

9
Abhay Kumar

これがあなたにできることです。それを達成する方法はたくさんありますが。

DateTime? d = null;    
if (txtBirthDate.Text == string.Empty)
    objinfo.BirthDate = d;
else
    objinfo.BirthDate =  DateTime.Parse(txtBirthDate.Text);

注:これは、データベースの日時列がNullを許可する場合にのみ機能します。それ以外の場合は、DateTimeの標準の最小値を定義できます。

3
Praveen Nambiar

私はこの関数を使用して解析します

public static bool TryParseSqlDateTime(string someval, DateTimeFormatInfo dateTimeFormats, out DateTime tryDate)
    {
        bool valid = false;
        tryDate = (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue;
        System.Data.SqlTypes.SqlDateTime sdt;
        if (DateTime.TryParse(someval, dateTimeFormats, DateTimeStyles.None, out tryDate))
        {
            try
            {
                sdt = new System.Data.SqlTypes.SqlDateTime(tryDate);
                valid = true;
            }
            catch (System.Data.SqlTypes.SqlTypeException ex)
            {

            }
        }

        return valid;
    }
3
liorlevi1974

簡単に言えば、do n'tDateTime.MinVaueをデフォルト値として使用します。

使用している環境に応じて、いくつかの異なるMinValuesがあります。

私はかつて、Windows CEプロジェクトを実装するプロジェクトを持っていました。フレームワークのDateTime.MinValue(0001年)、データベースMinValue(1753)、およびUIコントロールDateTimePicker( 1970年だったと思います)。そのため、少なくともつの異なるMinValuesがあり、奇妙な動作と予期しない結果につながっていました。 (そして、4番目(!)のバージョンもあったと思いますが、どこから来たのか思い出せません。).

nullableデータベースフィールドを使用し、代わりに値をNullable<DateTime>に変更します。コード内に有効な値なしがある場合、notもデータベース内の値である必要があります。 :-)

2
Jens H

MSDNから:

1753年1月1日から9999年12月31日までの日付と時刻のデータ。精度は100分の1秒(3.33ミリ秒)です。値は、.000、.003、または.007ミリ秒の増分に丸められます。 2つの4バイト整数として格納されます。最初の4バイトには、1900年1月1日の基準日の前後の日数が格納されます。基準日は、システムの基準日です。 1753年1月1日より前の日時の値は許可されません。他の4バイトには、午前0時からのミリ秒数で表される時刻が格納されます。秒の有効範囲は0〜59です。

SQLは、DateTime値にC#とは異なるシステムを使用します。

MinValueをセンチネル値として使用できます。MinValueの場合は、nullをオブジェクトに渡します(そして、DBにnullableとして日付を保存します)。

if(date == dateTime.Minvalue)
    objinfo.BirthDate = null;
2
Dave Bish

さて... SQLの最小日付を取得するのは非常に簡単です

DateTime sqlMinDateAsNetDateTime = System.Data.SqlTypes.SqlDateTime.MinValue.Value;
1
Richard Barker

DATETIME2を使用する場合、パラメーターを特にDATETIME2として渡す必要がある場合があります。そうしないと、パラメーターをDATETIMEに変換すると同じ問題が発生する場合があります。

command.Parameters.Add("@FirstRegistration",SqlDbType.DateTime2).Value = installation.FirstRegistration;
1
David Homer