Domanda

Qual è il modo idiomatico per ottenere l'ora del sistema come a LocalDateTime nel tempo di Noda?Il metodo più diretto a cui potrei pensare sarebbe

var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);

ma dato che Noda Time's l'intero scopo è sostituire DateTime con qualcosa che abbia una semantica più gradevole, ho pensato che ci fosse un metodo preferito da utilizzare DateTime nel modo sopra indicato.Il meglio che sono riuscito a trovare utilizzando le strutture di Noda è

var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;

ma questo sembra abbastanza prolisso.

È stato utile?

Soluzione

Il tuo secondo esempio è esattamente come lo faresti.È intenzionalmente prolisso.Vedere La filosofia progettuale di Noda Time.

Pensatelo in tre parti:

  1. Ottieni il momento attuale nel tempo:

    // Instant now = SystemClock.Instance.Now;               // NodaTime 1.x
    Instant now = SystemClock.Instance.GetCurrentInstant();  // NodaTime 2.x
    
  2. Ottieni il fuso orario del sistema.(Questa è la sintassi preferita)

    DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
    
  3. Applicare il fuso orario all'istante:

    ZonedDateTime zdt = now.InZone(tz);
    

Il tuo ultimo passo per ottenere un file LocalDateTime è banale, ma riconosci che quando lo fai, stai eliminando qualsiasi informazione sul fuso orario."Locale" in NodaTime lo fa non significa "locale al computer su cui è in esecuzione il codice".(In altre parole, non è così DateTimeKind.Local)

Ulteriori cose a cui pensare:

  • Potresti preferire astrarre l'orologio usando il file IClock interfaccia:

    IClock clock = SystemClock.Instance;
    // Instant now = clock.Now;               // NodaTime 1.x
    Instant now = clock.GetCurrentInstant();  // NodaTime 2.x
    

    Quindi potresti passare l'orologio come parametro del metodo o iniettarlo con il tuo framework DI/IoC preferito.(Autofac, Ninject, StructureMap, qualunque cosa...).Il vantaggio è che potresti usare a NodaTime.Testing.FakeClock durante i test unitari.Vedere Test unitari con Noda Time per ulteriori dettagli.

  • Potresti anche preferire passare il file DateTimeZone così puoi eseguire il tuo codice ovunque senza essere vincolato al fuso orario del sistema.Questo è importante per le applicazioni server, ma meno per le app desktop/mobili.

  • Se hai altri lavori che utilizzano i fusi orari IANA o se stai utilizzando la build .NET Standard di Noda Time, modifica il passaggio 2 per utilizzare il Tzdb fornitore:

    DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
    

    Le zone TZDB sono molto più precise delle zone BCL.Noda Time mapperà il fuso orario Windows (BCL) del tuo sistema su un fuso orario IANA (TZDB) in questa chiamata iniziale.

Se hai curiosità sul perché DateTime.Now è così compatto mentre Noda Time è così dettagliato, prova a decompilare DateTime.Now o guardando le fonti di riferimento degli Stati membri.Vedrai che sta facendo essenzialmente gli stessi passaggi sotto il cofano.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top