Now.Now为NodaTime

Chu*_*age 25 c# nodatime

我正试图让Jon Skeet(以及其他人)使用Noda Time框架.

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

是吗:

Instant now = new Instant(DateTime.Now.ToUniversalTime().Ticks);
Run Code Online (Sandbox Code Playgroud)

还是?

Instant now = Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime());
Run Code Online (Sandbox Code Playgroud)

它们是等价的,我甚至做得对吗?

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

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

Cri*_*scu 34

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

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

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

这将允许您:

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

我发现这非常有用.我认为拥有类似new Instant()Instant.Now返回当前时间会使得更难以硬编码SystemClock封底的用法,因此错过了NodaTime提供的测试优势.

有关使用NodaTime进行单元测试的更多信息,请参阅此链接.


关于你的代码示例:它们不等同.

  • Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()) 确实会给你UTC当前的瞬间.
  • new Instant(DateTime.Now.ToUniversalTime().Ticks)将来会给你一个错误的日期,因为BCL DateTime.Ticks表示自那以来的刻度数1/1/0001,NodaTime Instant.Ticks表示自那以来的刻度数1/1/1970(见这里的评论).


Mic*_*Liu 14

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

Instant now = SystemClock.Instance.Now;
Run Code Online (Sandbox Code Playgroud)

但您可能需要注意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... 
    }
}
Run Code Online (Sandbox Code Playgroud)

Logger在生产代码中实例化a 时,可以给它SystemClock.Instance.但是在Logger课堂的单元测试中,你可以给它一个FakeClock.