c# - DateTime ToLocalTime 失败

标签 c# mongodb

我正在使用 MongoDB 数据库。我知道当您将 DateTime 插入 Mongo 时,它会将其转换为 UTC。但是我正在做一个单元测试,我的断言失败了。

[TestMethod]
public void MongoDateConversion() {
    DateTime beforeInsert = DateTime.Now;
    DateTime afterInsert;

    Car entity = new Car {
        Name = "Putt putt",
        LastTimestamp = beforeInsert
    };

    // insert 'entity'
    // update 'entity' from the database

    afterInsert = entity.LastTimestamp.ToLocalTime();

    Assert.AreEqual(beforeInsert, afterInsert); // fails here
}

我一定遗漏了一些明显的东西。当我查看调试器时,我可以看到日期时间匹配,但断言仍然说它们不匹配(但确实如此):

Result Message: Assert.AreEqual failed. Expected:<5/21/2015 8:27:04 PM>. Actual:<5/21/2015 8:27:04 PM>.

有什么想法我在这里做错了吗?

编辑:

我提出了两种可能的解决方案,这两种解决方案都需要我记住做某事(这并不总是最好的依靠...):

一种是使用扩展方法来截断从数据库中出来的任何日期时间:

public static DateTime Truncate(this DateTime dateTime) {
    var timeSpan = TimeSpan.FromMilliseconds(1);
    var ticks = -(dateTime.Ticks % timeSpan.Ticks);
    return dateTime.AddTicks(ticks);
}

其他,看完http://alexmg.com/datetime-precision-with-mongodb-and-the-c-driver/ , 是标记 POCO 类中的任何 DateTime:

public class Car : IEntity {
    public Guid Id { get; set; }

    [BsonDateTimeOptions(Representation = BsonType.Document)]
    public DateTime LastTimestamp { get; set; }
}

最佳答案

MongoDB 将 DateTimes 存储为自 UNIX 纪元以来的 64 位毫秒计数。请参阅此页面:http://alexmg.com/datetime-precision-with-mongodb-and-the-c-driver/

由于 .NET 的 DateTime 的分辨率是 100 纳秒,因此 MongoDB 几乎可以肯定会像这样截断您往返的任何 DateTime 时间。

你有几个选择。

选项 1:确保在设置时截断 LastTimestamp,或在插入记录之前截断:

long excessTicks = timestamp.Ticks % 10000;

timestamp= new DateTime(
    ticks: timestamp.Ticks - excessTicks, 
    kind: timestamp.Kind
);

这种方法很容易出错。设置 LastTimestamp 的任何人都必须记住截断它,或者您可以在插入记录之前截断值,但您可能需要意外更改 CLR 对象。

或者,您可以使用 getter/setter 并在每次设置时将 LastTimestamp 截断为毫秒。但这可能会导致其他一些单元测试进一步失败,原因与此测试失败的原因完全相同。

选项 2:如果亚毫秒精度不重要,只需在断言中添加一些容差即可:

TimeSpan delta = beforeInsert - afterInsert;

Assert.IsTrue(Math.Abs(delta.TotalMilliseconds) <= 2);

关于c# - DateTime ToLocalTime 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30386601/

相关文章:

c# - 您何时使用 StringBuilder.AppendLine/string.Format 与 StringBuilder.AppendFormat?

ruby - 将字符串转换为货币格式

javascript - 无法使用 Mongoose 保存 JavaScript 对象

ruby - 在哪里以及如何对模型进行自定义验证?

c# - 如何覆盖 Xamarin.IOS UIButton 的 LayoutSublayersOfLayer 行为?

c# - 尝试单击按钮登录网站(Httpwebrequest - cookies)

c# BsonSerializer : deserialization through backing fields 收藏

image - 在 Mongodb 中存储图像并使用 Nodejs 为它们提供服务

c# - 如何使用 MVVM 模式在 WPF 中将一个 "disable"设为一个按钮?

c# - 与泛型建立关系