从C#

时间:2017-08-12 19:29:02

标签: c# mongodb datetime

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

我的问题是,为什么日期时间存储在MongoDb的本地,尽管从UI发送UTC日期时间。我希望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的新手。

4 个答案:

答案 0 :(得分: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 datetime

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

  • Local Date Time
      

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

因此,这是mongo DB UI的情况,Compass始终以用户的本地日期格式显示存储的数据,但Robo3T或mongoDB shell则不是这种情况。 除非明确指定将日期存储在本地,否则MongoDB始终以UTC格式存储日期。

答案 3 :(得分:0)

MongoDB提供了一个自动完成技巧的属性。

[BsonDateTimeOptions(Kind = DateTimeKind.Local)]

所以您只需要在TestDate属性上添加此属性