2015-01-09 21 views
9

Jaki jest zalecany sposób utworzenia instancji LocalDate, która reprezentuje "dzisiaj". Spodziewałem się, że w klasie LocalDate pojawią się statyczne właściwości "Teraz" lub "Dzisiaj", ale nie ma. Obecnie używam DateTime.Now:Utwórz NodaTime LocalDate reprezentujący "dzisiaj"

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

Czy istnieje lepszy sposób?

Odpowiedz

15

Najpierw zauważ, że kiedy mówisz "dzisiaj", odpowiedź może być różna dla różnych osób w różnych częściach świata. Dlatego, aby uzyskać aktualną datę lokalną, musisz mieć na uwadze strefę czasową.

Noda Czas prawidłowo modeluje to, podając Instant po wywołaniu Now z implementacji , takiej jak zegar systemowy. Chwila jest uniwersalna, więc wystarczy ją przekonwertować na strefę czasową, aby uzyskać lokalną datę strefy czasowej.

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

To jest minimalny kod. Oczywiście, jeśli chcesz korzystać z lokalnej strefy czasowej komputera (jak to zrobiłeś z DateTime.Now), można uzyskać go tak:

DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault(); 

I rzeczywiście wdrożyć go prawidłowo, należy zadzwonić .Now z interfejsu IClock , dzięki czemu można zastąpić zegar systemowy fałszywym zegarem dla testów jednostkowych.

Jest to doskonały przykład tego, jak Noda Time celowo nie ukrywa przed tobą rzeczy. Wszystko to dzieje się nadal pod maską, kiedy dzwonisz pod numer DateTime.Now, ale po prostu go nie widzisz. You can read more about Noda Time's design philosophy in the user guide.

11

Odpowiedź Matta jest ważna dla Noda Time 1.x.

W Nodzie czasu 2.0, wprowadzam ZonedClock, który jest w zasadzie połączeniem IClock i DateTimeZone. Ponieważ prawdopodobnie wiele razy chcesz bieżącego czasu w tej samej strefie czasowej, możesz wstrzyknąć (zakładając, że korzystasz z iniekcji zależności) i zachować to, a następnie użyć go. Na przykład:

class SomeClass 
{ 
    private readonly ZonedClock clock; 

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

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

Normalnie będzie dostarczyć ZonedClock przez przyjęcie IClock i przy użyciu jednego z nowych metod rozszerzenie, np

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

pamiętać, że kod nie zadziała 1.x 2.x w każdym razie - ja usunięcie właściwość Now z IClock jak to naprawdę nie powinno być nieruchomość (biorąc pod uwagę sposób, w jaki zmienia) - teraz jest to metoda GetCurrentInstant() .;

+0

Podoba mi się. 2.0 cały czas wygląda lepiej! –