【问题标题】:How to save date properly?如何正确保存日期?
【发布时间】:2011-12-25 04:29:15
【问题描述】:

我正在尝试保存日期(使用 C# 官方驱动程序):

val = DateTime.Parse(value).Date; //Here date is {11/11/2011 12:00:00 AM}
var update = Update.Set("Date", val);
...

当我从数据库中选择日期时,值为 {11/10/2011 10:00:00 PM}

如何只保存我想要的日期?

【问题讨论】:

    标签: mongodb mongodb-.net-driver


    【解决方案1】:

    在我的情况下,[BsonDateTimeOptions(Kind = DateTimeKind.Local)] 不起作用。

    下面是我做的

        DateTime _someDateProperty ;
        public DateTime SomeDateProperty 
        {
            get { return _someDateProperty ; }
            set
            {
                _someDateProperty = new DateTime(value.Ticks, DateTimeKind.Local);
            }
        }
    

    【讨论】:

      【解决方案2】:

      默认情况下(没有额外设置)c# 驱动程序将本地日期作为 utc 日期保存到数据库中(日期 - 时区偏移量),但无需任何操作即可读取(因此,utc 日期)。

      因此,当您从数据库加载日期时间时,您会在 2 小时内收到差异(您的时区偏移量)。 mongodb c#驱动程序在反序列化期间将utc日期转换为本地时区日期有两种方法:

      1.通过特定日期字段的属性:

      [BsonDateTimeOptions(Kind = DateTimeKind.Local)]
      public DateTime SomeDateProperty {get;set;}
      

      2.通过所有日期时间字段的全局设置(默认为UtcInstance):

      DateTimeSerializationOptions.Defaults = DateTimeSerializationOptions.LocalInstance;
      

      执行 #1 或 #2 后,您将看到本地日期。

      更新:


      #2 在最新的驱动程序版本中已过时,因此请改用以下代码:

      BsonSerializer.RegisterSerializer(typeof(DateTime), 
                   new DateTimeSerializer(DateTimeSerializationOptions.LocalInstance));
      

      更新:


      #2 又变了:

      BsonSerializer.RegisterSerializer(typeof(DateTime), DateTimeSerializer.LocalInstance);
      

      【讨论】:

      • 我尝试了第二种解决方案并收到以下警告:“MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions.Defaults 已过时:使用所需选项创建并注册 DateTimeSerializer。”
      • 在我的单元测试项目中使用 RegisterSerializer 我收到此错误:SetUp:MongoDB.Bson.BsonSerializationException:已经为 System.DateTime 类型注册了一个序列化程序。它只在第一次工作
      • 在 mongo 中将日期保存为双(秒)UTC,然后在拉出时在客户端进行翻译不是更容易吗?
      • 在使用 [BsonDateTimeOptions(Kind = DateTimeKind.UTC)] 时仍会将我的日期转换为 UTC
      【解决方案3】:

      2.2.4.26又变了:

      BsonSerializer.RegisterSerializer(typeof(DateTime), DateTimeSerializer.LocalInstance);
      

      【讨论】:

        【解决方案4】:

        Mongo 以 UTC 存储所有内容,以防您的日期时间是 UTC,这将有所帮助

        val = DateTime.SpecifyKind(val , DateTimeKind.Utc);
        var update = Update.Set("Date", val);
        

        【讨论】:

          【解决方案5】:

          您遇到了时区问题。您的日期对象可能位于 UTC 以外的时区(看起来提前 2 小时),或者您的默认时区设置为 UTC 以外的其他时区。驱动程序会将日期转换为适当的时区,然后再将其存储到数据库中。

          通常您不会注意到这一点,因为反向(从数据库中检索 UTC 日期)应该将其转换回原始时区。您正在使用的驱动程序可能存在问题,或者 C# 可能需要更多代码才能正确处理。

          将日期存储为字符串通常不是一个好主意,因为它会禁用日期范围查询。

          【讨论】:

            【解决方案6】:

            Mongodb 以“UTC DateTime”格式存储的日期值,包括日期和时间。所以你不能单独在字段中存储日期。相反,您可以在从 mongo 检索后在应用程序代码中单独获取日期部分。

            就像在 c# 中一样

            datevalue.ToString("MM/dd/yyyy");
            

            datevalue.ToShortDateString() 
            

            【讨论】:

            • 这在获取午夜日期时不起作用。在夏令时期间,他们会被调回前一天晚上 11 点...
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-11-17
            • 2023-03-28
            • 2020-09-21
            • 1970-01-01
            • 2021-01-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多