C#、SQL Server、Entity Framework で発生する "Conversion of a datetime2 data type to a datetime data type results out-of-range value" エラーの解決方法
C#、SQL Server、Entity Framework で発生する "datetime2 データ型から datetime データ型への変換で範囲外の値が発生する" エラーについて
概要
原因
datetime2
データ型は、datetime
データ型よりも広い範囲の日付と時刻を表現できます。そのため、datetime2
データ型の値を datetime
データ型に変換すると、値が範囲外になる可能性があります。
解決策
このエラーを解決するには、以下の方法があります。
- datetime2 データ型の値を datetime データ型の範囲内に収まるように変換する
var datetime2Value = new DateTimeOffset(2024, 3, 30, 10, 10, 10, 100);
var datetimeValue = datetime2Value.DateTime; // エラーが発生する
// 範囲内に収まるように変換
datetimeValue = datetime2Value.Date; // 日付のみを取り出す
datetimeValue = datetime2Value.ToLocalTime().Date; // ローカル時刻の日付のみを取り出す
- 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();
}
}
}
}
このコードは、以下の手順で実行できます。
- Visual Studio で新しい C# コンソール アプリケーションを作成します。
- 上記のコードをコード ファイルに貼り付けます。
- NuGet パッケージ マネージャーを使用して、
EntityFramework
パッケージをインストールします。 - 接続文字列を
app.config
ファイルに追加します。
<configuration>
<connectionStrings>
<add name="MyDatabase" connectionString="Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=True" />
</connectionStrings>
</configuration>
- アプリケーションを実行します。
このコードを実行すると、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