如何创建一个代表“今天”的LocalDate实例是推荐的方式?我原本期望在LocalDate类中有一个静态的"Now"或"Today"属性,但实际上却没有。我目前的方法是使用DateTime.Now:
var now = DateTime.Now;
LocalDate today = new LocalDate(now.Year, now.Month, now.Day);
有更好的方法吗?
// 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();
Matt的回答对于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();
...
}
}
通常您会通过使用其中一个新的扩展方法,例如,获取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()
方法。Jon的回答是正确的,但我认为把所有内容放在一起会更有帮助。对于NodaTime 2.x:
SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime().Date
LocalDate today = DateTime.Now.ToLocalDateTime().Date;
Now
,而不是系统时区。
对于NodaTime 3.x://Tz is a DateTimeZone object, constructed from current user's preferred timezone ID
SystemClock.Instance.InZone(Tz).GetCurrentZonedDateTime();
你也可以根据使用情况使用GetCurrentLocalDateTime
或GetCurrentOffsetDateTime
。
ZonedClock
应该注册为什么生命周期? - Oskar