创建一个代表"今天"的NodaTime LocalDate;

时间:2015-01-09 03:30:56

标签: c# .net nodatime

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

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

有更好的方法吗?

4 个答案:

答案 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,它基本上是IClockDateTimeZone的组合。由于您可能希望多次在同一时区中使用当前时间,因此您可以注入(我假设您正在使用依赖注入)并保留该时间,然后使用它。例如:

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();

您也可以根据您的用例使用 GetCurrentLocalDateTimeGetCurrentOffsetDateTime