2015-01-09 9 views
9

Qual è il modo consigliato per creare un'istanza di LocalDate che rappresenta "oggi". Mi aspettavo che ci fosse una proprietà "Now" o "Today" statica nella classe LocalDate, ma non c'è. Il mio approccio attuale è quello di utilizzare DateTime.Now:Creare un LocalDate NodaTime che rappresenti "oggi"

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

C'è un modo migliore?

risposta

15

Per prima cosa riconosci che quando dici "oggi", la risposta potrebbe essere diversa per persone diverse in diverse parti del mondo. Pertanto, al fine di ottenere la data locale corrente, è necessario avere un fuso orario in mente.

Noda Time modella correttamente questo dandoti un Instant quando si chiama Now da un'implementazione IClock come l'orologio di sistema. Un istante è universale, quindi è sufficiente convertirlo in un certo fuso orario per ottenere la data locale di quel fuso orario.

// 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; 

Questo è il codice minimo. Naturalmente, se si desidera utilizzare il fuso orario locale del computer (come avete fatto con DateTime.Now), è possibile ottenere in questo modo:

DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 

E per davvero implementare in modo corretto, è necessario chiamare .Now dall'interfaccia IClock , in modo tale da poter sostituire l'orologio di sistema con un falso orologio per i test dell'unità.

Questo è un ottimo esempio di come Noda Time intenzionalmente non nasconda le cose da voi. Tutto questo è ancora in corso sotto il cofano quando chiami DateTime.Now, ma semplicemente non lo vedi. You can read more about Noda Time's design philosophy in the user guide.

11

La risposta di Matt è azzeccata per Noda Time 1.x.

In Noda Time 2.0, sto introducendo un ZonedClock, che è fondamentalmente una combinazione di IClock e un DateTimeZone. Poiché è probabile che tu desideri che l'ora corrente si trovi nello stesso fuso orario più volte, puoi iniettarla (presumo che tu stia utilizzando l'iniezione di dipendenza) e conservarla, quindi usarla. Ad esempio:

class SomeClass 
{ 
    private readonly ZonedClock clock; 

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

    internal void DoSomethingWithDate() 
    { 
     LocalDate today = clock.GetCurrentDate(); 
     ... 
    } 
} 

che normalmente fornisce la ZonedClock prendendo un IClock e utilizzando uno dei nuovi metodi di estensione, ad esempio

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

Nota che il codice 1.x non funziona in 2.x in ogni caso - sto rimuovendo la proprietà Now da IClock come in realtà non dovrebbe essere una proprietà (dato il modo in cui cambia) - è ora un metodo GetCurrentInstant() .;

+0

Mi piace. 2.0 sembra sempre meglio! –

Problemi correlati