如何使用 Entity Framework Core 正确保存 DateTime?

Posted

技术标签:

【中文标题】如何使用 Entity Framework Core 正确保存 DateTime?【英文标题】:How to correctly save DateTime using Entity Framework Core? 【发布时间】:2021-02-13 10:15:58 【问题描述】:

我有一个包含 DateTime 属性的类。如何使用 Entity Framework Core 正确节省时间?下面我举个例子。

我使用 TIMESTAMP 格式将 DateTime 存储在数据库中。我有一个时区 +3(莫斯科)的服务器和数据库(mysql)。

SELECT TIMEDIFF(current_timestamp(), utc_timestamp()); // result = 03:00:00

我还有一个可以在不同用户的PC上运行的程序。程序将包含 DateTime 属性的对象保存在数据库中:

obj.DateTime = DateTime.Parse("2020-10-13T19:00:00+0300");

现在我们来看几种情况:


    程序在时区 +3(莫斯科)

    的 PC 上启动

    Console.WriteLine(obj.DateTime?.ToString()); // 2020-10-13 19:00:00

我使用 phpMyAdmin 检查数据库中的数据,我看到 2020-10-13 19:00:00。一切都好。 PC的时区等于数据库的时区,所以我们看到的结果是一样的。


    程序在+6:30(仰光)时区的PC上打开

    Console.WriteLine(obj.DateTime?.ToString()); // 13.10.2020 22:30:00

我使用 phpMyAdmin 检查数据库中的数据,我看到 2020-10-13 22:30:00。 失败! 我应该在 19:00 而不是 22:30 同时看到所有内容。 obj.DateTime 属性包含相同的时间!


我现在如何理解这些记录包含相等时间?为什么 EF 不将 DateTime 转换为 UTC?

【问题讨论】:

服务器的时区是固定的,您可以从用户计算机上获取时区信息,现在您可以在保存前更正它。当然反之亦然 如果您在服务器上保留 UTC 时间,然后在访问服务器(读取或写入)时应用本地时区特定的更正,您可能会发现这更容易。您可能还想查看 Noda Time (nodatime.org)。它消除了很多 .NET 的时间怪异 【参考方案1】:

如果您想根据特定区域保存 DateTime,而不是服务器时间,我建议您创建一个服务,并且每次调用该服务而不是调用 DateTime。 有一个名为 TimeZoneInfo 的类,它代表世界上的任何时区,它在 system 命名空间中可用。

确保您没有使用 DateTime 直接获取当前日期

DateTime now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time")); 

这会将协调世界时 (UTC) 转换为指定时区的时间。 您可以在https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones

中找到有关区域 ID 的更多信息

如果你使用依赖注入:

public class DateTimeService : IDateTime

    public DateTime Now => TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));


public interface IDateTime

    DateTime Now  get; 

或者如果您更喜欢使用 Helper 类:

public static class DateTimeHelper

    public static DateTime Now() => TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time"));

【讨论】:

以上是关于如何使用 Entity Framework Core 正确保存 DateTime?的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework 学习系列 - 认识理解Entity Framework

如何使用 Entity Framework Core 模拟异步存储库

如何使用 Entity Framework 生成和自动递增 Id

如何使用 Entity Framework Core 正确保存 DateTime?

如何使用 Entity Framework Core 获取主键值

如何在 Entity Framework 6 中使用 DbDataReader 获取表名?