创建表示"今天"的NodaTime LocalDate

Red*_*ran 18 .net c# nodatime

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

var now = DateTime.Now;
LocalDate today = new LocalDate(now.Year, now.Month, now.Day);
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Mat*_*int 20

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

Instant当您Now从IClock系统时钟等实现中调用时,Noda Time会正确地对此进行建模.瞬间是通用的,因此您只需将其转换为某个时区即可获得该时区的本地日期.

// 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;
Run Code Online (Sandbox Code Playgroud)

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

DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
Run Code Online (Sandbox Code Playgroud)

要真正实现它,你应该.Now从IClock界面调用,这样你就可以用假时钟代替系统时钟进行单元测试.

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


Jon*_*eet 16

Matt's answer is spot on for Noda Time 1.x.

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

class SomeClass
{
    private readonly ZonedClock clock;

    internal SomeClass(ZonedClock clock)
    { 
        this.clock = clock;
    }

    internal void DoSomethingWithDate()
    {
        LocalDate today = clock.GetCurrentDate();
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您通常会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();
Run Code Online (Sandbox Code Playgroud)

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

  • @Oskar:几乎肯定不是——但你是拥有这里所有背景的人。野田时间方面没有什么特别的事情发生。 (2认同)

Pat*_*ski 8

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

SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime().Date
Run Code Online (Sandbox Code Playgroud)