创建一个代表“今天”的NodaTime LocalDate

建议表示“今天”的LocalDate实例的建议方法是什么。 我期待在LocalDate类中有一个静态的“Now”或“Today”属性,但是没有。 我目前的方法是使用DateTime.Now:

var now = DateTime.Now; LocalDate today = new LocalDate(now.Year, now.Month, now.Day); 

有没有更好的办法?

首先要认识到,当你说“今天”时,对于世界不同地区的不同人来说,答案可能会有所不同。 因此,为了获得当前的本地日期,您必须考虑时区。

当您从IClock实现(如系统时钟)调用Now时,Noda Time会通过给您一个Instant正确建模。 瞬间是通用的,因此您只需将其转换为某个时区即可获得该时区的本地日期。

 // get the current time from the system clock Instant now = SystemClock.Instance.Now; // get a time zone DateTimeZone tz = DateTimeZoneProviders.Tzdb["Asia/Tokyo"]; // use now and tz to get "today" LocalDate today = now.InZone(tz).Date; 

这是最小的代码。 当然,如果你想使用计算机的本地时区(就像你使用DateTime.Now ),你可以这样做:

 DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 

要真正正确地实现它,你应该从IClock接口调用IClock ,这样你就可以用假时钟代替系统时钟进行unit testing。

这是Noda Time故意不向您隐瞒事情的一个很好的例子。 当你调用DateTime.Now ,所有这些仍然在引擎盖下,但你只是看不到它。 您可以在用户指南中阅读有关Noda Time的设计理念的更多信息 。

对于Noda Time 1.x来说,马特的回答是现实的。

在Noda Time 2.0中,我介绍了一个ZonedClock ,它基本上是IClockDateTimeZone的组合。 由于您可能需要多次在同一时区中的当前时间,您可以注入(我假设您正在使用dependency injection)并保留它,然后使用它。 例如:

 class SomeClass { private readonly ZonedClock clock; internal SomeClass(ZonedClock clock) { this.clock = clock; } internal void DoSomethingWithDate() { LocalDate today = clock.GetCurrentDate(); ... } } 

您通常会通过采用IClock并使用其中一种新的扩展方法来提供ZonedClock ,例如

 var clock = SystemClock.Instance; var zoned = clock.InUtc(); // Or... var zoned = clock.InZone(DateTimeZoneProviders.Tzdb["Europe/London"]; // Or... var zoned = clock.InTzdbSystemDefaultZone(); // Or... var zoned = clock.InBclSystemDefaultZone(); 

请注意,你的1.x代码无论如何都不能在2.x中运行 – 我正在从IClock删除Now属性,因为它实际上不应该是属性(给定它改变的方式) – 它现在是一个GetCurrentInstant()方法。

乔恩的答案是正确的,但我认为将它们放在一起是有帮助的。 对于NodaTime 2.x:

 SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime().Date