2015-01-09 4 views
9

Welcher ist die empfohlene Methode zum Erstellen einer LocalDate-Instanz, die "heute" darstellt? Ich habe erwartet, dass in der LocalDate-Klasse eine statische "Now" - oder "Today" -Eigenschaft vorhanden ist, aber nicht. Mein aktueller Ansatz ist die Verwendung von DateTime.Now:Erstellen Sie ein NodaTime LocalDate, das "heute" darstellt.

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

Gibt es einen besseren Weg?

Antwort

15

Zuerst erkennen, dass, wenn Sie "heute" sagen, die Antwort für verschiedene Menschen in verschiedenen Teilen der Welt unterschiedlich sein könnte. Um das aktuelle lokale Datum zu erhalten, müssen Sie daher eine Zeitzone berücksichtigen.

Noda Zeit modelliert dies korrekt, indem Sie eine Instant, wenn Sie Now von einer IClock Implementierung wie die Systemuhr aufrufen. Ein Instant ist universell, Sie müssen ihn also nur in eine bestimmte Zeitzone konvertieren, um das lokale Datum der Zeitzone zu erhalten.

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

Das ist der minimale Code. Natürlich, wenn Sie den Computer des lokalen Zeitzone verwenden möchten (wie Sie mit DateTime.Now tat), können Sie es wie so erhalten:

DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 

Und wirklich, es richtig zu implementieren, sollten Sie .Now von der IClock Schnittstelle aufrufen , so dass Sie die Systemuhr durch eine falsche Uhr für Ihre Komponententests ersetzen könnten.

Dies ist ein großartiges Beispiel dafür, wie Noda Time vorsätzlich nicht die Dinge vor dir verbirgt. All das passiert immer noch unter der Haube, wenn Sie DateTime.Now anrufen, aber Sie sehen es einfach nicht. You can read more about Noda Time's design philosophy in the user guide.

11

Matts Antwort ist genau richtig für Noda Time 1.x.

In Noda Time 2.0, stelle ich eine , die im Grunde eine Kombination von IClock und DateTimeZone ist. Da die aktuelle Uhrzeit wahrscheinlich mehrmals in der gleichen Zeitzone angezeigt werden soll, können Sie diese injizieren (ich nehme an, dass Sie die Abhängigkeitsinjektion verwenden) und diese beibehalten und dann verwenden. Zum Beispiel:

class SomeClass 
{ 
    private readonly ZonedClock clock; 

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

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

würden Sie liefern normalerweise die ZonedClock durch eine IClock zu nehmen und eine der neuen Erweiterungsmethoden, z.B.

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

Beachten Sie, dass Ihr Code 1.x nicht sowieso in 2.x arbeiten - ich bin die Now Eigenschaft von IClock entfernen, wie es wirklich nicht eine Eigenschaft (angesichts der Art und Weise ändert) sein sollte - es ist jetzt ein GetCurrentInstant()-Verfahren.

+0

Ich mag es. 2.0 sieht immer besser aus! –

Verwandte Themen