【问题标题】:How can I turn UTC Timezone off for MongoDB如何为 MongoDB 关闭 UTC 时区
【发布时间】:2020-11-08 16:53:51
【问题描述】:

由于MongoDB stores times in UTC by default.,我正在为 MongoDB 日期字段使用下面的扩展名 罢工>

    public static class DateTimeExtensions {
    
        public static DateTime AdjustUtcDiffByOffset(this DateTime time) {
            return time.AddHours(DateTimeOffset.Now.Offset.Hours);
        }
    }
}
尽管我在应用程序级别尝试了一些方法,例如 .NET 中的属性或序列化方法,但它们都会导致不同的问题。我现在决定在 .NET 中使用这个扩展,但我认为这也不是一个完整而准确的解决方案。

在不依赖于编程语言的情况下,在数据库级别是否有任何解决方案?

编辑

我认为我应该在下面的 cmets 之后进行更多解释。如上所示,我已经知道 MongoDB 以 UTC 格式存储在这篇文章中链接的时间。这可能很有用,但我的应用程序不需要任何 UTC 时区差异,我不想分别处理每种编程语言的表示层。而且,我什至不希望在其他层中只增加一个额外的行或函数,因为它比基本逻辑或业务更远。

让我的架构承担这个责任。我很懒惰,生命真的很短暂,鸟儿在外面飞:) 我不希望不同的字段像不必要的字符串转换一样。由于我在应用程序中进行很多时间计算,因此我需要数据库中的日期时间类型。

我现在使用.NET,因此MongoDB .NET driver。我尝试了不同的序列化方法,但它在数据访问体系结构中引起了另一个问题。 总之,我可以在我的另一个应用程序中使用 UTC,但我现在不想要它,我更喜欢分配给该字段时的本地时间。我决定特别为 C# 使用下面的封装。

    private DateTime _startTime;
    public DateTime StartTime {
        get => _startTime;
        set => _startTime = new DateTime(value.Ticks, DateTimeKind.Utc);
    }

【问题讨论】:

  • 你能详细说明问题是什么吗?被认为是“最佳实践”,仅以一种日期格式(标准为 UTC)工作以避免不一致。这种“最佳实践”给您带来问题的事实应该令人担忧。
  • 你能澄清一下你要解决什么问题吗?是否将所有时间戳存储在UTC以外的某个特定时区?是否将原始时区与 MongoDB 中的值一起存储?不管怎样,这感觉更像是一个序列化/反序列化的问题——毕竟,MongoDB 实际存储的是一个 64 位整数,代表世界历史上的一个时刻,而不是任何时区的时钟时间。
  • 包含的 sn-p 似乎扭曲了时间戳。这可能表明对时区存在一些误解。时间戳只是在一个时区中表示。将小时数添加到存储的时间戳不会转换时区 - 它会创建一个完全不同的时间戳。 Mongo 将所有时间戳表示存储为 UTC。如果稍后,某些逻辑需要不同的时区,它可以从 UTC 时间戳转换。这在所有系统和平台中得到广泛支持。
  • 帖子中链接的 Mongo 文档对此非常清楚:MongoDB 默认以 UTC 存储时间,并将任何本地时间表示形式转换为这种形式。必须操作或报告某些未修改的本地时间值的应用程序可以将时区与 UTC 时间戳一起存储,并在其应用程序逻辑中计算原始本地时间。
  • @IMSoP 一种不针对每种编程语言处理 UI 的解决方案。这对于国际应用程序很有用,但我现在正在编写本地应用程序。也许你不介意 UI,但你不应该为每个人等待这个。感谢您的帮助或解释,但我不想为此争论。当我分配给该字段时,我更喜欢使用。当然,您或其他人可能不喜欢。谢谢

标签: c# mongodb datetime utc


【解决方案1】:

我认为从 db 级别是不可能的。我所做的是为日期属性编写自定义设置器,这将强制 mongoDB 假定时间已经在 UTC 中,从而避免如下转换:

private DateTime _createdUTC;
public DateTime CreatedUtc
  {
     get
       {
         return _createdUTC;
       }
     set
       {
         _createdUTC = new DateTime(value.Ticks, DateTimeKind.Utc);
       }
  }

【讨论】:

  • 我不明白这将用于什么场景:您似乎有一个带有一些时区信息的对象,而您正在强行丢弃该时区信息。为什么对象有不正确的信息,为什么只在保存时丢弃它很重要,而不是在应用程序本身中使用它时?
  • 假设你有一个 UTC 时间存储在 sql db 中。当您获取它并移至 mongo 时,mongo 会再次将其转换为 UTC,因为默认情况下未指定日期类型。这种方法可以通过告诉 mongo 日期已经是 utc 来避免这种情况
  • @NithinChandran 是的,我在同时使用两者时遇到了麻烦。数据库级别似乎不可能,但您的封装比我的扩展更明智。 +1
  • @NithinChandran 听起来您的问题出在 SQL 驱动程序中,而不是 MongoDB 驱动程序中:当您检索该日期并将其反序列化为一个对象时,该对象应该被标记为 UTC,而不是作为“未知时区”。
  • 也许你是对的。获取日期作为 UTC 本身可能会解决问题。然而,这对我来说是一个解决方案。无论如何感谢您注意到它
【解决方案2】:

MongoDB 始终以 UTC 保存日期。

您可以做的就是告诉客户,他在从数据库中检索数据时必须将日期转换为本地日期。

您可以在实例化客户端之前注册一个序列化程序:

BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance);
var client = new MongoClient(options) ...

【讨论】:

    猜你喜欢
    • 2021-08-02
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2019-10-30
    • 2019-07-14
    相关资源
    最近更新 更多