首页 文章

从C#发送UTC DateTime时,本地DateTime存储在MongoDb中

提问于
浏览 1499
1

我将从我的C#winform应用程序发送的UTC日期时间发送到MongoDb 3.4.5,但它在MongoDb中存储为本地时间 . 当我从Mongo获取数据时,它返回UTC时间 .

我的问题是为什么datetime存储在MongoDb的本地,尽管从UI发送UTC Datetime . 我希望UTC时间存储在MongoDb中 . 以下是代码段:

public void InsertInMongo()
    {
        var client = new MongoClient("mongodb://localhost:27017");
        var db = client.GetDatabase("Test");
        var col = db.GetCollection<TestData>("TestData");

        var data = new TestData(123,DateTime.UtcNow);
        col.InsertOne(data);

        var fromMongo = col.Find(Builders<TestData>.Filter.Empty).ToList();

    }
}

class TestData
{
    public TestData(int num, DateTime date)
    {
        TestNumber = num;
        TestDate = date;
    }
    [BsonId]
    [BsonElement("_id")]
    [BsonRepresentation(BsonType.ObjectId)]
    [BsonIgnoreIfDefault]
    public string Id { get; private set; }
    public int TestNumber { get; set; }

    public DateTime TestDate { get; set; }
}
}

Stored Data in MongoDb

我该如何解决这个问题?我是使用C#在Mongo的新手 .

2 回答

  • 2

    您需要像这样声明自定义 DateTimeSerializer

    public class BsonUtcDateTimeSerializer : DateTimeSerializer
    {
        public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            return new DateTime(base.Deserialize(context, args).Ticks, DateTimeKind.Unspecified);
        }
    
        public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
        {
            var utcValue = new DateTime(value.Ticks, DateTimeKind.Utc);
            base.Serialize(context, args, utcValue);
        }
    }
    

    然后你需要在创建连接后注册;这样的事情:

    var server = new MongoClient("mongodb://127.0.0.1");
    var database = server.GetDatabase("Test");
    var collection = database.GetCollection<MyObject>("MyObject");
    
    BsonSerializer.RegisterSerializer(typeof(DateTime), new BsonUtcDateTimeSerializer());
    

    编辑:

    BSON Date是一个64位整数,表示自Unix纪元(1970年1月1日)以来的毫秒数 . 这导致过去和未来的可表示日期范围约为2.9亿年 . 官方BSON规范将BSON日期类型称为UTC日期时间 .

    因此,MongoDB中的日期以UTC毫秒为单位,那么从MongoDB中获取数据的应用程序会以本地化格式显示它们 .

    MongoDB默认以UTC格式存储时间,并将任何本地时间表示转换为此形式 . 必须操作或报告某些未修改的本地时间值的应用程序可以将时区与UTC时间戳一起存储,并在其应用程序逻辑中计算原始本地时间 .

  • 0

    我想你将不得不转换回特定的时区 . 您需要确定UTC时间与从mongo获得的时间之间的偏差 . 如果没有偏移,那么Mongo也将它存储为UTC,我打赌这种情况正在发生 . 我怀疑,例如,你会发现它是区域性的,如EST . 一旦 Build 了时区信息,您就可以使用 TimeZoneInfo 对象或类似的东西从一个区域转换为另一个区域,但是,您需要知道要转换为的时区 .

相关问题