在 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
更可取的方法。我能想到的最好的使用野田的设施是
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
,这样您就可以在任何地方运行您的代码,而不受系统时区的限制。这对于服务器应用程序很重要,但对于桌面/移动应用程序则不那么重要。如果您有其他使用 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 引用源。您会发现它在后台执行基本相同的步骤。
关于c# - 在 Noda Time 中获取系统的 LocalDateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21029489/