在蒙古语中存储Utc和本地日期时间

本文关键字:日期 时间 Utc 蒙古语 存储 | 更新日期: 2023-09-27 18:16:48

我有一个Mongo c#实现,它将日期时间存储为UTC。

MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions options = 
    MongoDB.Bson.Serialization.Options.DateTimeSerializationOptions.UtcInstance;
var serializer = 
    new MongoDB.Bson.Serialization.Serializers.DateTimeSerializer(options);
MongoDB.Bson.Serialization.BsonSerializer.RegisterSerializer(
    typeof(DateTime),
    serializer);

我还需要将用户本地时区与UTC一起存储。为了解释这一点,我有两个类似

的属性
DateTime WorkItemToCompleteBy{get; set;}
[BsonDateTimeOptions(Kind = DateTimeKind.Unspecified)]
DateTime WorkItemToCompleteByLocal{get; set;}

我想在Local属性中存储澳大利亚/美国/印度/其他时间,在另一个属性中存储各自的UTC值。因为我要处理几十个时区,所以我有代码将UTC转换为所需的时区,并将其存储在WorkItemToCompleteByLocal属性中。我希望Mongo存储这个值'as-is'并将其返回给我。问题是Mongo总是将其存储为ISODate并将值转换为Utc版本。解释一下。如果UTC是0730小时,我计算布里斯班时间为1730小时,并将其设置为WorkitemToCompleteByLocal,它们被保存为

"WorkItemToCompleteBy" : ISODate("2013-06-05T07:30:00Z"),
"WorkItemToCompleteByLocal" : ISODate("2013-06-05T12:00:00Z"),

Mongo将提供的时间解释为本地时间,服务器位于印度,并将其转换为相当于1200小时的UTC。虽然它检索值回到1730 (IST虽然),但它违背了我的目的,并阻止我在Mongo上运行任何基于本地时间的查询。我没有主意了。任何帮助,帮助存储WorkItemToCompleteByLocal日期'As-Is',不需要修改

在蒙古语中存储Utc和本地日期时间

这是我强制MongoDB存储原始值的方式,并忽略DateTime对象中的DateTimeKind属性。

这可能不适用于您的业务逻辑,但对于我们的特殊原因是有意义的。

BsonSerializer.RegisterSerializer(typeof(DateTime), new MyMongoDBDateTimeSerializer());

public class MyMongoDBDateTimeSerializer : DateTimeSerializer
{
    //  MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic
    //  We overwrite it to be DateTimeKind.Unspecified
    public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, System.Type nominalType, MongoDB.Bson.Serialization.IBsonSerializationOptions options)
    {
        var obj = base.Deserialize(bsonReader, nominalType, options);
        var dt = (DateTime) obj;
        return new DateTime(dt.Ticks, DateTimeKind.Unspecified);
    }
    //  MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic
    //  We overwrite it to be DateTimeKind.Unspecified
    public override object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, MongoDB.Bson.Serialization.IBsonSerializationOptions options)
    {
        var obj = base.Deserialize(bsonReader, nominalType, actualType, options);
        var dt = (DateTime)obj;
        return new DateTime(dt.Ticks, DateTimeKind.Unspecified);
    }
    //  MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first
    //  We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value
    public override void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, System.Type nominalType, object value, MongoDB.Bson.Serialization.IBsonSerializationOptions options)
    {
        var dt = (DateTime) value;
        var utcValue = new DateTime(dt.Ticks, DateTimeKind.Utc);
        base.Serialize(bsonWriter, nominalType, utcValue, options);
    }
}

新版本的c#驱动程序=>

    public class MyMongoDBDateTimeSerializer : DateTimeSerializer
{
    //  MongoDB returns datetime as DateTimeKind.Utc, which cann't be used in our timezone conversion logic
    //  We overwrite it to be DateTimeKind.Unspecified
    public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var obj = base.Deserialize(context, args);
        return new DateTime(obj.Ticks, DateTimeKind.Unspecified);
    }
    //  MongoDB stores all datetime as Utc, any datetime value DateTimeKind is not DateTimeKind.Utc, will be converted to Utc first
    //  We overwrite it to be DateTimeKind.Utc, becasue we want to preserve the raw value
    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
    {
        var utcValue = new DateTime(value.Ticks, DateTimeKind.Utc);
        base.Serialize(context, args, utcValue);
    }
}

在。net driver version 2.4中,使用如下:

using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
BsonSerializer.RegisterSerializer(DateTimeSerializer.LocalInstance);

这样,datetime值将以kind=utc存储在db中,但在本地kind中反序列化。