Instant.Now为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”标题。
我做了一些研究,似乎NodaTime的方式是根据时钟得到现在的时刻。
如果要使用系统时钟获取当前时间,只需使用SystemClock.Instance.GetCurrentInstant()
。
但是,不要直接在代码中使用SystemClock.Instance
,而是最好在时间感知类中注入IClock
依赖项。
这将允许您:
- 在运行时为类提供
SystemClock.Instance
,因此代码将使用正确的时间 - 在unit testing期间提供
IClock
的伪实现,以允许您根据需要调整时间以测试各种场景(如时间的推移)。 有一个NodaTime.Testing项目提供了一个名为FakeClock
的类。
我发现这非常有用。 我认为有一些像new Instant()
或Instant.Now
返回当前时间将使得更容易硬编码SystemClock
用法,因此缺少NodaTime提供的测试优势。
有关使用NodaTime进行unit testing的更多信息,请参阅此链接 。
关于您的代码示例:它们不等同。
-
Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime())
确实会以UTCInstant.FromDateTimeUtc(DateTime.Now.ToUniversalTime())
给你当前的瞬间。 -
new Instant(DateTime.Now.ToUniversalTime().Ticks)
将来会给你一个错误的日期,因为BCL的DateTime.Ticks
表示自1/1/0001
以来的刻度1/1/0001
,而NodaTime的Instant.Ticks
表示数字自1/1/1970
以来的蜱虫(见这里的评论)。
SystemClock.Now
将当前时间作为Instant
值返回:
Instant now = SystemClock.Instance.Now;
但您可能需要注意IClock
接口文档中的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
类的unit testing中,你可以给它一个FakeClock
。