获取系统的 LocalDateTime(Noda 时间)
题
获取系统时间的惯用方法是什么 LocalDateTime
在野田时间?我能想到的最直接的方法是
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
但考虑到野田时间 整个目的是用具有更好语义的东西替换 DateTime, ,我认为有一种比使用更好的方法 DateTime
以上述方式。使用野田的设施我能想到的最好的办法是
var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
但这似乎很冗长。
解决方案
你的第二个例子正是你将如何做到这一点。这是 故意地 冗长。看 野田时代的设计理念.
分为三个部分来思考:
获取当前时刻:
// Instant now = SystemClock.Instance.Now; // NodaTime 1.x Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x
获取系统的时区。(这是首选语法)
DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
将时区应用于即时:
ZonedDateTime zdt = now.InZone(tz);
您获得的最后一步 LocalDateTime
是微不足道的,但要认识到,当您这样做时,您将删除任何时区信息。NodaTime 中的“本地”确实 不是 意思是“运行代码的计算机本地”。(换句话说,这并不像 DateTimeKind.Local
)
其他需要考虑的事情:
您可能更喜欢使用抽象时钟
IClock
界面:IClock clock = SystemClock.Instance; // Instant now = clock.Now; // NodaTime 1.x Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
然后,您可以将时钟作为方法参数传递,或者将其注入您最喜欢的 DI/IoC 框架。(Autofac、Ninject、StructureMap,等等……)。优点是你可以使用
NodaTime.Testing.FakeClock
在单元测试期间。看 使用 Noda Time 进行单元测试 更多细节。您可能还希望传递
DateTimeZone
因此您可以在任何地方运行代码,而不受系统时区的限制。这对于服务器应用程序很重要,但对于桌面/移动应用程序则不那么重要。如果您有其他工作使用 IANA 时区,或者您使用的是 Noda Time 的 .NET Standard 版本,则更改步骤 2 以使用
Tzdb
提供者:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
TZDB 区域比 BCL 区域准确得多。在此初始调用中,Noda Time 会将您系统的 Windows (BCL) 时区映射到 IANA (TZDB) 时区。
如果您对原因感到好奇 DateTime.Now
太紧凑而Noda Time太冗长,尝试反编译 DateTime.Now
或查看 MS 参考源。您会发现它在幕后执行的步骤基本相同。