Obtenir le LocalDateTime du système en heure Noda
Question
Quelle est la manière idiomatique d'obtenir l'heure du système en tant que LocalDateTime
à l'heure de Noda ?La méthode la plus directe à laquelle je pourrais penser serait
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
mais étant donné que Noda Time le but est de remplacer DateTime par quelque chose qui a une sémantique plus agréable, j'ai supposé qu'il y avait une méthode préférable à celle d'utiliser DateTime
de la manière ci-dessus.Le mieux que j'ai pu trouver en utilisant les installations de Noda est
var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
mais cela semble assez verbeux.
La solution
Votre deuxième exemple montre exactement comment vous procéderiez.C'est intentionnellement verbeux.Voir La philosophie de conception de Noda Time.
Pensez-y en trois parties :
Obtenez le moment actuel :
// Instant now = SystemClock.Instance.Now; // NodaTime 1.x Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x
Obtenez le fuseau horaire du système.(C'est la syntaxe préférée)
DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
Appliquer le fuseau horaire à l'instant :
ZonedDateTime zdt = now.InZone(tz);
Votre dernière étape pour obtenir un LocalDateTime
est trivial, mais sachez que lorsque vous le faites, vous supprimez toutes les informations de fuseau horaire."Local" dans NodaTime le fait pas signifie "local à l'ordinateur sur lequel le code est exécuté".(En d'autres termes, ce n'est pas comme DateTimeKind.Local
)
Points supplémentaires à prendre en compte :
Vous préférerez peut-être abstraire l'horloge en utilisant le
IClock
interface:IClock clock = SystemClock.Instance; // Instant now = clock.Now; // NodaTime 1.x Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
Ensuite, vous pouvez transmettre l'horloge en tant que paramètre de méthode ou l'injecter avec votre framework DI/IoC préféré.(Autofac, Ninject, StructureMap, peu importe...).L'avantage est que vous pouvez alors utiliser un
NodaTime.Testing.FakeClock
lors de vos tests unitaires.Voir Tests unitaires avec Noda Time pour plus de détails.Vous préférerez peut-être aussi passer dans le
DateTimeZone
afin que vous puissiez exécuter votre code n'importe où sans être lié au fuseau horaire du système.Ceci est important pour les applications serveur, mais moins pour les applications de bureau/mobiles.Si vous avez d'autres travaux qui utilisent les fuseaux horaires IANA, ou si vous utilisez la version .NET Standard de Noda Time, modifiez l'étape 2 pour utiliser la
Tzdb
fournisseur:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
Les zones TZDB sont beaucoup plus précises que les zones BCL.Noda Time mappera le fuseau horaire Windows (BCL) de votre système à un fuseau horaire IANA (TZDB) lors de cet appel initial.
Si vous êtes curieux de savoir pourquoi DateTime.Now
est si compact alors que Noda Time est si verbeux, essayez de décompiler DateTime.Now
ou en regardant les sources de référence MS.Vous verrez qu'il effectue essentiellement les mêmes étapes sous le capot.