Now.Now为NodaTime

时间:2013-01-25 22:55:07

标签: c# nodatime

我正在尝试使用Jon Skeet(和其他人)使用Noda Time框架。

我正在尝试现在存储当前(即时)。 Instant是从长时间刻度创建的,但是现在当前Ticks的数量是多少?

是吗:

Instant now = new Instant(DateTime.Now.ToUniversalTime().Ticks);

和或?

Instant now = Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime());

它们是否相同,我甚至是这样做的吗?

PS,如果Jon回答这个问题 - 我想提出一个Instant.Now属性。

PS2我知道标题包含一个标签,但它不会让我有一个简短的“Instant.Now”标题。

2 个答案:

答案 0 :(得分:32)

我做了一些研究,似乎NodaTime方式是根据clock得到现在的时刻。

如果您想使用系统时钟获取当前时间,请使用SystemClock.Instance.GetCurrentInstant()

但是,不是直接在代码中使用SystemClock.Instance,而是在时间感知类中注入IClock依赖项。

这将允许您:

  • 在运行时为类提供SystemClock.Instance,因此代码将使用正确的时间
  • 在单元测试期间提供IClock的虚假实现,以允许您根据需要调整时间以测试各种场景(如时间的推移)。有一个NodaTime.Testing项目提供了一个名为FakeClock
  • 的类

我发现这非常有用。我认为让new Instant()Instant.Now之类的内容返回当前时间会更容易硬编码SystemClock的用法,因此错过了NodaTime提供的测试优势。

有关使用NodaTime进行单元测试的更多信息,请参阅this link


关于您的代码示例:它们不等同。

  • Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime())确实会以UTC格式给你当前的瞬间。
  • new Instant(DateTime.Now.ToUniversalTime().Ticks)将来会给你一个错误的日期,因为BCL的DateTime.Ticks表示自1/1/0001以来的刻度数,而NodaTime的Instant.Ticks表示的数量为1/1/1970自{{1}}以来的标记(请参阅评论here)。

答案 1 :(得分:14)

SystemClock.Now将当前时间作为Instant值返回:

Instant now = SystemClock.Instance.Now;

但您可能需要注意IClock界面文档中的注释:

  

IClock 适用于您需要访问当前时间的任何地方。虽然直接调用SystemClock.Instance.Now并非严格不正确,但与您调用UtcNow的方式相同,但强烈建议不要将其视为生产代码的样式。我们建议为需要它的任何东西提供 IClock 的实例,这允许您使用NodaTime.Testing程序集(或您自己的实现)中的存根时钟编写测试。

举个简单的例子,假设您有一个需要当前时间的Logger类。不要直接访问SystemClock,而是使用通过其构造函数提供的IClock实例:

public class Logger
{
    private readonly IClock clock;

    public Logger(IClock clock)
    {
        this.clock = clock;
    }

    public void Log(string message)
    {
        Instant timestamp = this.clock.Now;
        // Now log the message with the timestamp... 
    }
}

在生产代码中实例化Logger时,您可以为其SystemClock.Instance。但是在Logger课程的单元测试中,您可以给它FakeClock