C#、SQL Server、Entity Framework で発生する "Conversion of a datetime2 data type to a datetime data type results out-of-range value" エラーの解決方法

2024-04-02

C#、SQL Server、Entity Framework で発生する "datetime2 データ型から datetime データ型への変換で範囲外の値が発生する" エラーについて

概要

原因

datetime2 データ型は、datetime データ型よりも広い範囲の日付と時刻を表現できます。そのため、datetime2 データ型の値を datetime データ型に変換すると、値が範囲外になる可能性があります。

解決策

このエラーを解決するには、以下の方法があります。

  1. datetime2 データ型の値を datetime データ型の範囲内に収まるように変換する
var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);
var datetimeValue = datetime2Value.DateTime; // エラーが発生する

// 範囲内に収まるように変換
datetimeValue = datetime2Value.Date; // 日付のみを取り出す
datetimeValue = datetime2Value.ToLocalTime().Date; // ローカル時刻の日付のみを取り出す
  1. datetime データ型の精度を上げる
var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

// datetime データ型の精度をミリ秒まで上げる
var datetimeValue = datetime2Value.ToDateTime(TimeSpan.FromMilliseconds(1));
var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

// Entity Framework で `datetime2` データ型を使用する
var entity = new MyEntity
{
    Datetime2Value = datetime2Value
};

context.SaveChanges();

補足

  • SQL Server では、datetime2 データ型は、1753 年 1 月 1 日から 9999 年 12 月 31 日までの範囲の日付と時刻を表現できます。
  • Entity Framework では、datetime2 データ型は DateTimeOffset 型としてマップされます。



using System;
using System.Data.Entity;

namespace Example
{
    public class MyEntity
    {
        public int Id { get; set; }

        public DateTimeOffset Datetime2Value { get; set; }
    }

    public class MyContext : DbContext
    {
        public MyContext() : base("MyDatabase")
        {
        }

        public DbSet<MyEntity> MyEntities { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // `datetime2` データ型の値を作成
            var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

            // 範囲内に収まるように変換
            var datetimeValue = datetime2Value.Date;

            // Entity Framework で `datetime2` データ型を使用する
            using (var context = new MyContext())
            {
                var entity = new MyEntity
                {
                    Datetime2Value = datetime2Value
                };

                context.MyEntities.Add(entity);
                context.SaveChanges();
            }
        }
    }
}

このコードは、以下の手順で実行できます。

  1. Visual Studio で新しい C# コンソール アプリケーションを作成します。
  2. 上記のコードをコード ファイルに貼り付けます。
  3. NuGet パッケージ マネージャーを使用して、EntityFramework パッケージをインストールします。
  4. 接続文字列を app.config ファイルに追加します。
<configuration>
  <connectionStrings>
    <add name="MyDatabase" connectionString="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" />
  </connectionStrings>
</configuration>
  1. アプリケーションを実行します。

このコードを実行すると、MyEntities テーブルに Datetime2Value 列に値が格納されます。

このコードは、あくまでもサンプルです。実際のアプリケーションでは、必要に応じてコードを変更する必要があります。




"datetime2" データ型から "datetime" データ型への変換で範囲外の値が発生するエラーを解決するその他の方法

ToString() メソッドを使用する

var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

// "yyyy-MM-dd HH:mm:ss" の形式で文字列に変換
var datetimeValue = datetime2Value.ToString("yyyy-MM-dd HH:mm:ss");

// "yyyy-MM-dd" の形式で文字列に変換
var dateValue = datetime2Value.ToString("yyyy-MM-dd");

Parse() メソッドを使用する

var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

// "yyyy-MM-dd HH:mm:ss" の形式で文字列に変換
var datetimeValue = DateTime.Parse(datetime2Value.ToString("yyyy-MM-dd HH:mm:ss"));

// "yyyy-MM-dd" の形式で文字列に変換
var dateValue = DateTime.Parse(datetime2Value.ToString("yyyy-MM-dd"));

TryParse() メソッドを使用する

var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);

// "yyyy-MM-dd HH:mm:ss" の形式で文字列に変換
DateTime datetimeValue;
if (DateTime.TryParse(datetime2Value.ToString("yyyy-MM-dd HH:mm:ss"), out datetimeValue))
{
    // 変換成功
}
else
{
    // 変換失敗
}

// "yyyy-MM-dd" の形式で文字列に変換
DateTime dateValue;
if (DateTime.TryParse(datetime2Value.ToString("yyyy-MM-dd"), out dateValue))
{
    // 変換成功
}
else
{
    // 変換失敗
}
  • ToString() メソッドは、datetime2 データ型の値を文字列に変換します。
  • Parse() メソッドは、文字列を datetime データ型に変換します。
  • TryParse() メソッドは、文字列を datetime データ型に変換できるかどうかを判断し、変換できた場合は datetime データ型を返します。

c# sql-server entity-framework


C#、SQLite、System.Data.SQLiteにおけるユーザー定義関数の作成・使用: 他の方法

C#、SQLite、System. Data. SQLiteを用いて、ユーザー定義関数を作成・使用する方法について解説します。ユーザー定義関数とはSQLiteは、C#のようなプログラミング言語から直接アクセス可能な軽量なデータベースエンジンです。データベースに組み込み可能な独自の関数を作成したい場合、ユーザー定義関数を作成できます。...


安心・安全なデータ管理:C#でSQLiteデータベースを暗号化

SQLiteには、データベース全体を暗号化するための機能が組み込まれています。この機能を使用するには、以下の手順が必要です。System. Data. SQLite NuGetパッケージをプロジェクトに追加します。以下のコードを使用して、パスワードで保護されたデータベース接続を作成します。...


SQL Server CE 4.0 と SQLite のパフォーマンス徹底比較:最適なデータベースの選び方

この記事では、SQL Server CE 4.0 と SQLite のパフォーマンスを比較します。両方のデータベースは、埋め込み型データベースとしてよく使用されますが、それぞれ異なる長所と短所があります。パフォーマンス一般的に、SQL Server CE は SQLite よりも高速です。これは、SQL Server CE がより高度なクエリエンジンとストレージエンジンを使用しているためです。ただし、このパフォーマンスの違いは、ワークロードによって異なります。...


SQL SQL SQL SQL Amazon で見る



なぜ SQL Server における datetime 型の最小値は 1753-01-01 なのか?

SQL Server における datetime 型の最小値は 1753-01-01 00:00:00. 000 です。これは、SQL Server が Sybase から派生したためであり、Sybase が採用していた日付システムに由来します。