Quelqu'un peut-il expliquer la différence entre System.DateTime.Now
et System.DateTime.Today
en C # .NET? Avantages et inconvénients de chacun si possible.
DateTime.Now
Renvoie une valeur DateTime
composée de la date et de l'heure locales de l'ordinateur sur lequel le code est exécuté. Il a DateTimeKind.Local
Attribué à sa propriété Kind
. Cela revient à appeler l’un des moyens suivants:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
Renvoie une valeur DateTime
qui comporte les mêmes composants année, mois et jour que toutes les expressions ci-dessus, mais dont les composants heure sont définis sur zéro. Il a également DateTimeKind.Local
Dans sa propriété Kind
. Cela équivaut à l'un des éléments suivants:
DateTime.Now.Date
DateTime.UtcNow.ToLocalTime().Date
DateTimeOffset.UtcNow.LocalDateTime.Date
DateTimeOffset.Now.LocalDateTime.Date
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).Date
Notez qu'en interne, l'horloge système est exprimée en UTC. Par conséquent, lorsque vous appelez DateTime.Now
, Il obtient d'abord l'heure UTC (via la fonction GetSystemTimeAsFileTime
de l'API Win32. ) puis convertit la valeur dans le fuseau horaire local. (Par conséquent, DateTime.Now.ToUniversalTime()
est plus cher que DateTime.UtcNow
.)
Notez également que DateTimeOffset.Now.DateTime
Aura des valeurs similaires à DateTime.Now
, Mais aura DateTimeKind.Unspecified
Plutôt que DateTimeKind.Local
- ce qui pourrait entraîner d'autres erreurs en fonction de ce que vous faire avec.
Donc, la réponse simple est que DateTime.Today
Est équivalent à DateTime.Now.Date
.
Mais IMHO - Vous ne devriez utiliser ni l’un ni l’autre de ces équivalents.
Lorsque vous demandez DateTime.Now
, Vous demandez la valeur de l'horloge de calendrier locale de l'ordinateur sur lequel le code est exécuté. Mais ce que vous récupérez ne contient aucune information sur cette horloge! Le meilleur que vous obtenez est que DateTime.Now.Kind == DateTimeKind.Local
. Mais à qui appartient ce lieu? Ces informations sont perdues dès que vous modifiez la valeur, par exemple en la stockant dans une base de données, en l'affichant à l'écran ou en la transmettant à l'aide d'un service Web.
Si votre fuseau horaire local respecte les règles de l'heure d'été, vous ne récupérez pas ces informations à partir de DateTime.Now
. Dans des moments ambigus, comme lors d'une transition "de repli", vous ne saurez pas lequel des deux moments possibles correspond à la valeur que vous avez récupérée avec DateTime.Now
. Par exemple, supposons que votre fuseau horaire système soit défini sur Mountain Time (US & Canada)
et que vous demandiez DateTime.Now
Aux premières heures du 3 novembre 2013. Que signifie le résultat 2013-11-03 01:00:00
? Il y a deux moments instantanés représentés par cette même date et heure du calendrier. Si j'envoyais cette valeur à quelqu'un d'autre, ils n'auraient aucune idée de laquelle je voulais dire. Surtout s'ils se trouvent dans un fuseau horaire où les règles sont différentes.
La meilleure chose à faire serait d'utiliser DateTimeOffset
à la place:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Maintenant, pour le même scénario que celui décrit ci-dessus, j'obtiens la valeur 2013-11-03 01:00:00 -0600
Avant la transition ou 2013-11-03 01:00:00 -0700
Après la transition. Quiconque regarde ces valeurs peut dire ce que je voulais dire.
J'ai écrit un article de blog sur ce sujet même. Veuillez lire - The Case Against DateTime.Now .
De plus, il y a des endroits dans ce monde (comme le Brésil) où la transition "printemps-avant" a lieu exactement à minuit. Les horloges vont de 23h59 à 01h00. Cela signifie que la valeur que vous obtenez pour DateTime.Today
À cette date, n'existe pas ! Même si vous utilisez DateTimeOffset.Now.Date
, Vous obtenez le même résultat, et vous avez toujours ce problème. C’est parce que traditionnellement, il n’existait pas d’objet Date
dans .Net. Donc quelle que soit la manière dont vous obtenez la valeur, une fois que vous supprimez l'heure - vous devez vous rappeler que cela ne représente pas vraiment "minuit", même si c'est la valeur avec laquelle vous travaillez.
Si vous voulez vraiment une solution totalement correcte à ce problème, la meilleure approche consiste à utiliser NodaTime . La classe LocalDate
représente correctement une date sans heure. Vous pouvez obtenir la date actuelle pour n’importe quel fuseau horaire, y compris le fuseau horaire du système local:
using NodaTime;
...
Instant now = SystemClock.Instance.Now;
DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;
DateTimeZone zone2 = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;
Si vous ne voulez pas utiliser Noda Time, il existe maintenant une autre option. J'ai contribué à la mise en œuvre d'un objet comportant uniquement une date dans le projet . Net CoreFX Lab . Vous pouvez trouver l'objet de package System.Time
Dans leur flux MyGet. Une fois ajouté à votre projet, vous constaterez que vous pouvez effectuer les opérations suivantes:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
Temps. .Now
comprend le 09:23:12 ou autre; .Today
est la date seulement (à 00:00:00 ce jour-là).
Alors utilisez .Now
si vous voulez inclure l'heure, et .Today
si vous voulez juste la date!
.Today
est essentiellement identique à .Now.Date
Le DateTime.Now
propriété retourne la date et l'heure actuelles, par exemple 2011-07-01 10:09.45310
.
Le DateTime.Today
La propriété _ renvoie la date actuelle avec les composants d’heure définis sur zéro, par exemple 2011-07-01 00:00.00000
.
Le DateTime.Today
la propriété est réellement implémentée pour retourner DateTime.Now.Date
:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
DateTime.Today représente la date système actuelle avec la partie heure définie sur 00:00:00
et
DateTime.Now représente la date et l'heure actuelles du système
J'ai pensé à ajouter ces liens -
Pour revenir à la question initiale, en utilisant Reflector, j’ai expliqué la différence de code.
public static DateTime Today
{
get
{
return DateTime.Now.Date; // It returns the date part of Now
//Date Property
// returns same date as this instance, and the time value set to 12:00:00 midnight (00:00:00)
}
}
private const long TicksPerMillisecond = 10000L;
private const long TicksPerDay = 864000000000L;
private const int MillisPerDay = 86400000;
public DateTime Date
{
get
{
long internalTicks = this.InternalTicks; // Date this instance is converted to Ticks
return new DateTime((ulong) (internalTicks - internalTicks % 864000000000L) | this.InternalKind);
// Modulo of TicksPerDay is subtracted - which brings the time to Midnight time
}
}
public static DateTime Now
{
get
{
/* this is why I guess Jon Skeet is recommending to use UtcNow as you can see in one of the above comment*/
DateTime utcNow = DateTime.UtcNow;
/* After this i guess it is Timezone conversion */
bool isAmbiguousLocalDst = false;
long ticks1 = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
long ticks2 = utcNow.Ticks + ticks1;
if (ticks2 > 3155378975999999999L)
return new DateTime(3155378975999999999L, DateTimeKind.Local);
if (ticks2 < 0L)
return new DateTime(0L, DateTimeKind.Local);
else
return new DateTime(ticks2, DateTimeKind.Local, isAmbiguousLocalDst);
}
}
DateTime dt = new DateTime();// gives 01/01/0001 12:00:00 AM
DateTime dt = DateTime.Now;// gives today date with current time
DateTime dt = DateTime.Today;// gives today date and 12:00:00 AM time
DateTime.Today
est DateTime.Now
avec le temps mis à zéro.
Il est important de noter qu’il existe une différence entre une valeur DateTime, qui représente le nombre de ticks écoulés depuis le 1er janvier 0000 à minuit, et la représentation sous forme de chaîne de cette valeur DateTime, qui exprime une valeur de date et d’heure dans Format spécifique à la culture: https://msdn.Microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks
est l’heure réelle stockée par .net (essentiellement l’heure UTC), le reste ne représente que représentations (importantes pour l’affichage).
Si la propriété Kind
est DateTimeKind.Local
il implicitement inclut les informations de fuseau horaire de l'ordinateur local. Lors de l'envoi sur un service Web .net, les valeurs DateTime sont sérialisées par défaut avec les informations de fuseau horaire incluses, par exemple. 2008-10-31T15: 07: 38.6875000-05: 00, et un ordinateur dans un autre fuseau horaire peut toujours savoir exactement à quelle heure il est fait référence.
Donc, utiliser DateTime.Now et DateTime.Today est parfaitement OK.
Vous commencez généralement à avoir des problèmes lorsque vous commencez à confondre la représentation de chaîne avec la valeur réelle et essayez de "réparer" le DateTime, quand il n'est pas cassé.