建议表示"今天"的LocalDate实例的推荐方法是什么?我期待有一个静态的"现在"或"今天" LocalDate类中的属性,但没有。我目前的方法是使用DateTime.Now:
var now = DateTime.Now;
LocalDate today = new LocalDate(now.Year, now.Month, now.Day);
有更好的方法吗?
答案 0 :(得分:19)
首先要认识到,当你说“今天”时,对于世界不同地区的不同人来说,答案可能会有所不同。因此,为了获得当前的本地日期,您必须牢记时区。
当您从Instant
实施(例如系统时钟)调用Now
时,Noda Time会为您提供IClock
,从而对此进行正确建模。瞬间是通用的,因此您只需将其转换为某个时区即可获得该时区的本地日期。
// 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();
要真正正确地实现它,你应该从.Now
接口调用IClock
,这样你就可以用假时钟代替系统时钟进行单元测试。
这是Noda Time如何故意不向您隐瞒事情的一个很好的例子。当你拨打DateTime.Now
时,所有这一切仍在幕后进行,但你只是看不到它。 You can read more about Noda Time's design philosophy in the user guide
答案 1 :(得分:13)
马特的答案是Noda Time 1.x的答案。
在Noda Time 2.0中,我引入了ZonedClock
,它基本上是IClock
和DateTimeZone
的组合。由于您可能希望多次在同一时区中使用当前时间,因此您可以注入(我假设您正在使用依赖注入)并保留该时间,然后使用它。例如:
class SomeClass
{
private readonly ZonedClock clock;
internal SomeClass(ZonedClock clock)
{
this.clock = clock;
}
internal void DoSomethingWithDate()
{
LocalDate today = clock.GetCurrentDate();
...
}
}
您通常会通过ZonedClock
并使用其中一种新的扩展方法提供IClock
,例如
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中工作 - 我从Now
移除IClock
属性,因为它确实不应该一个属性(给定它改变的方式) - 它现在是GetCurrentInstant()
方法。
答案 2 :(得分:1)
Jon的回答是正确的,但我认为将它们放在一起是有帮助的。对于NodaTime 2.x:
SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime().Date
答案 3 :(得分:0)
Patrick 的回答是正确的。
但是,您可能希望为当前用户的时区而不是系统的时区获取 Now
。
对于 NodaTime 3.x:
//Tz is a DateTimeZone object, constructed from current user's preferred timezone ID
SystemClock.Instance.InZone(Tz).GetCurrentZonedDateTime();
您也可以根据您的用例使用 GetCurrentLocalDateTime
或 GetCurrentOffsetDateTime
。