Quelqu'un peut-il expliquer la différence entre System.DateTime.Now
et System.DateTime.Today
en C # .NET? Le pour et le contre de chacun si possible.
Réponses
Trop de publicités?La réponse correcte est qu' DateTime.Today
est équivalent à DateTime.Now.Date
. Mais
À mon humble avis - Vous ne devriez pas utiliser l'une de ces.
Lorsque vous demandez DateTime.Now
, vous demandez la valeur du calendrier local de l'horloge de l'ordinateur que le code est en cours d'exécution sur. Mais ce que vous obtenez de retour n'a pas de renseignements sur l'horloge! Le mieux que vous obtenez, c'est que DateTime.Now.Kind == DateTimeKind.Local
. Mais qui est le local est-il? Cette information est perdue dès que vous faites quelque chose avec la valeur, comme les stocker dans une base de données, l'affichage sur l'écran, ou de la transmettre à l'aide d'un service web.
Si votre fuseau horaire local suit toute l'heure d'été règles, vous ne recevrez que les informations de retour d' DateTime.Now
. Dans ambiguë fois, comme lors d'un "repli" de la transition, vous ne saurez pas lequel des deux moments correspondent à la valeur que vous avez récupéré avec DateTime.Now
. Par exemple, supposons que votre système fuseau horaire est défini à l' Mountain Time (US & Canada)
et vous demander de l' DateTime.Now
dans les premières heures du 3 novembre 2013. Quel est le résultat 2013-11-03 01:00:00
moyenne? Il y a deux moments de l'instantané le temps est représenté par ce même calendrier datetime. Si je devais envoyer cette valeur à quelqu'un d'autre, ils n'ont aucune idée de qui je voulais dire. Surtout si elles sont dans une zone où les règles sont différentes.
La meilleure chose que vous pourriez faire serait d'utiliser DateTimeOffset
à la place:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Maintenant, pour le même scénario que j'ai 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 peuvent dire ce que je voulais dire.
J'ai récemment écrit un post de blog sur ce sujet. Lisez - Le Cas Contre DateTime.Maintenant.
Aussi, il y a certains endroits dans ce monde (comme le Brésil), où le "printemps" avec la transition se passe exactement à Minuit. Les horloges vont de 23:59 01:00. 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 encore ce problème. C'est parce qu'il n'y a pas une telle chose comme un Date
objet .Net. Donc, peu importe la façon dont vous obtenez est la valeur, une fois que vous dépouiller le temps - vous devez vous rappeler qu'il n'a pas vraiment représenter "minuit", même si c'est la valeur que vous travaillez avec.
Si vous voulez vraiment un tout à fait correcte solution à ce problème, la meilleure approche est d'utiliser NodaTime. L' LocalDate
classe représente correctement un jour sans qu'un temps. Vous pouvez obtenir la date actuelle pour n'importe quel fuseau horaire, y compris le système local time zone:
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;
La propriété DateTime.Now
renvoie la date et l'heure actuelles, par exemple 2011-07-01 10:09.45310
.
La propriété DateTime.Today
renvoie la date actuelle avec les composants de l'heure définis sur zéro, par exemple 2011-07-01 00:00.00000
.
La propriété DateTime.Today
est réellement implémentée pour renvoyer 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é à l'Ajout de ces liens -
- Une brève Histoire de DateTime - Par Anthony Moore par BCL équipe
- Choix entre Datetime DateTime et de Compenser par MSDN
- Ne pas oublier de SQL server 2008 est un nouveau Type de données que DateTimeOffset
- L' .NET Framework inclut les DateTime, DateTimeOffset, et TimeZoneInfo types, qui peuvent être utilisés pour créer des applications que le travail avec les dates et les heures.
- Effectuer des Opérations Arithmétiques avec des Dates et des heures-MSDN
Revenant à la question initiale , à l'Aide de Réflecteurs j'ai expliqué la différence dans le 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);
}
}