在Noda Time中以LocalDateTime
方式获取系统时间的惯用方式是什么?我能想到的最直接的方法是
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
但是考虑到Noda Time的entire purpose is to replace DateTime with something that has nicer semantics,我认为有一种比上述方式使用
DateTime
更好的方法。使用Noda的设备,我能想到的最好的方法是var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
但这似乎很冗长。
最佳答案
您的第二个示例正是您将如何执行此操作。它是故意冗长的。参见Noda Time's design philosophy。
分为三个部分来考虑:
// 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
接口(interface)来抽象时钟:IClock clock = SystemClock.Instance;
// Instant now = clock.Now; // NodaTime 1.x
Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
然后,您可以将时钟作为方法参数传入,或将其与您喜欢的DI/IoC框架一起注入(inject)。 (Autofac,Ninject,StructureMap等)。好处是您可以在单元测试期间使用
NodaTime.Testing.FakeClock
。有关更多详细信息,请参见Unit Testing with Noda Time。 DateTimeZone
,这样您就可以在任何地方运行代码,而不必受限于系统时区。这对服务器应用程序很重要,但对台式机/移动应用程序则不那么重要。 Tzdb
提供程序:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
TZDB区域比BCL区域准确得多。在此初始调用中,Noda Time会将系统的Windows(BCL)时区映射到IANA(TZDB)时区。
如果您对为什么Not Time如此冗长而
DateTime.Now
如此紧凑感到好奇,请尝试反编译DateTime.Now
或查看MS引用源。您会发现它在后台执行了基本上相同的步骤。