我正在尝试使用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”标题。
答案 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
。