获取系统时间的惯用方法是什么 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;

但这似乎很冗长。

有帮助吗?

解决方案

你的第二个例子正是你将如何做到这一点。这是 故意地 冗长。看 野田时代的设计理念.

分为三个部分来思考:

  1. 获取当前时刻:

    // Instant now = SystemClock.Instance.Now;               // NodaTime 1.x
    Instant now = SystemClock.Instance.GetCurrentInstant();  // NodaTime 2.x
    
  2. 获取系统的时区。(这是首选语法)

    DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
    
  3. 将时区应用于即时:

    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 参考源。您会发现它在幕后执行的步骤基本相同。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top