Herkes arasındaki farkı açıklayabilir System.DateTime.Now
ve System.DateTime.Today
C # .NET içinde? Mümkünse her birinin artıları ve eksileri.
Herkes arasındaki farkı açıklayabilir System.DateTime.Now
ve System.DateTime.Today
C # .NET içinde? Mümkünse her birinin artıları ve eksileri.
Yanıtlar:
DateTime.Now
DateTime
Kodun çalıştığı bilgisayarın yerel tarih ve saatinden oluşan bir değer döndürür . Bu gelmiştir DateTimeKind.Local
onun atanan Kind
özelliği. Aşağıdakilerden herhangi birini aramakla eşdeğerdir:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
DateTime
Yukarıdaki ifadelerden herhangi biriyle aynı yıl, ay ve gün bileşenlerine sahip, ancak zaman bileşenleri sıfır olarak ayarlanmış bir değer döndürür . Ayrıca vardır DateTimeKind.Local
onun içinde Kind
mülkiyet. Aşağıdakilerden herhangi birine eşdeğerdir:
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
Dahili olarak, sistem saatinin UTC cinsinden olduğunu unutmayın; bu nedenle, DateTime.Now
onu ilk aradığınızda UTC saatini alır ( GetSystemTimeAsFileTime
Win32 API'deki işlev aracılığıyla ) ve ardından değeri yerel saat dilimine dönüştürür. (Bu nedenle DateTime.Now.ToUniversalTime()
daha pahalıdır DateTime.UtcNow
.)
Ayrıca, DateTimeOffset.Now.DateTime
bunun ile benzer değerlere sahip olacağını DateTime.Now
, ancak bunun DateTimeKind.Unspecified
yerine sahip olacağını unutmayın - bununla DateTimeKind.Local
ne yaptığınıza bağlı olarak başka hatalara yol açabilir.
Yani, basit cevap DateTime.Today
şuna eşdeğerdir DateTime.Now.Date
.
Ancak IMHO - Bunlardan birini veya yukarıdaki eşdeğerlerini kullanmamalısınız.
İstediğinizde DateTime.Now
, kodun çalıştığı bilgisayarın yerel takvim saatinin değerini soruyorsunuz. Ama geri aldığın şey o saat hakkında hiçbir bilgi içermiyor! Aldığın en iyi şey bu DateTime.Now.Kind == DateTimeKind.Local
. Ama bu kimin yerel? Bir veri tabanında saklamak, ekranda göstermek veya bir web hizmeti kullanarak iletmek gibi değerle ilgili herhangi bir şey yaptığınız anda bu bilgiler kaybolur.
Yerel saat diliminiz herhangi bir yaz saati uygulaması kuralına uyuyorsa, bu bilgiyi buradan geri alamazsınız DateTime.Now
. "Geri dönüş" geçişi gibi belirsiz zamanlarda, iki olası andan hangisinin geri aldığınız değere karşılık geldiğini bilemezsiniz DateTime.Now
. Örneğin, sistem saat diliminizin olarak ayarlandığını Mountain Time (US & Canada)
ve DateTime.Now
3 Kasım 2013'ün erken saatlerinde 2013-11-03 01:00:00
istediğinizi varsayalım. Sonuç ne anlama geliyor? Aynı takvim tarih saati ile temsil edilen iki anlık zaman anı vardır. Bu değeri bir başkasına gönderirsem, hangisini kastettiğime dair hiçbir fikirleri olmazdı. Özellikle de kuralların farklı olduğu bir zaman dilimindeyse.
Yapabileceğiniz en iyi şey DateTimeOffset
bunun yerine kullanmak olacaktır :
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Şimdi, yukarıda anlattığım aynı senaryo için, değeri 2013-11-03 01:00:00 -0600
geçişten önce veya 2013-11-03 01:00:00 -0700
geçişten sonra alıyorum . Bu değerlere bakan herkes ne demek istediğimi anlayabilir.
Tam da bu konuda bir blog yazısı yazdım. Lütfen okuyun - DateTime.Now Karşısındaki Durum .
Ayrıca, bu dünyada (Brezilya gibi) "ileriye doğru ilkbahar" geçişinin tam olarak Gece Yarısında gerçekleştiği bazı yerler vardır. Saatler 23:59 ile 01:00 arasındadır. Bu DateTime.Today
, o tarihte aldığınız değerin mevcut olmadığı anlamına gelir ! Kullansanız bile DateTimeOffset.Now.Date
aynı sonucu alıyorsunuz ve hala bu sorunu yaşıyorsunuz. Çünkü geleneksel olarak Date
.Net'te nesne diye bir şey yoktur . Dolayısıyla, değeri nasıl elde ettiğinizden bağımsız olarak, zamanı bir kez çıkardığınızda - çalıştığınız değer bu olsa bile, bunun "gece yarısını" temsil etmediğini hatırlamanız gerekir.
Bu soruna gerçekten tam olarak doğru bir çözüm istiyorsanız, en iyi yaklaşım NodaTime kullanmaktır . LocalDate
Sınıf düzgün bir süre verilmeksizin bir tarih temsil eder. Yerel sistem saat dilimi de dahil olmak üzere herhangi bir saat dilimi için geçerli tarihi alabilirsiniz:
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;
Noda Time'ı kullanmak istemiyorsanız, şimdi başka bir seçenek var. Net CoreFX Lab projesine yalnızca tarih içeren bir nesnenin uygulanmasına katkıda bulundum . Sen bulabilirsiniz System.Time
onların MyGet yemlerde paket nesnesi. Projenize eklendikten sonra, aşağıdakilerden herhangi birini yapabileceğinizi göreceksiniz:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
DateTime.UtcNow
Uygulamanızda belirtebilirseniz veya değerin UTC olarak belirtilmesi kabul edilebilir. (Alan veya mülke aslında MyDateUtc
sadece MyDate
- ama bu sadece pastanın üzerine krema gibi bir şey demeyi seviyorum .) Spesifikasyon veya alan adında DateTimeOffset.UtcNow
bunu aktaramıyorsanız, sıfır ofsetinin aktarılmasını sağlamak için kullanılabilir. tarih ve saat değerleri ile.
DateTime.Now.Date
.
Zaman. .Now
09:23:12 veya her neyse içerir; .Today
yalnızca tarih bölümüdür (o gün saat 00:00:00).
Öyleyse .Now
, saati eklemek .Today
istiyorsanız ve sadece tarihi istiyorsanız kullanın!
.Today
esasen aynıdır .Now.Date
UtcNow
sürece kullanın . (Özellikle bir web uygulamasında bu neredeyse her zaman yanlış seçimdir.)
DateTime.Now
Mülkiyet örneğin geçerli tarih ve saati döndürür 2011-07-01 10:09.45310
.
DateTime.Today
Mülkiyet örneğin sıfıra ayarlanan saat bileşenlere sahip geçerli tarih döndürür 2011-07-01 00:00.00000
.
DateTime.Today
Mülkiyet aslında dönüş için uygulanır DateTime.Now.Date
:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
DateTime.Today , saat bölümü 00:00:00 olarak ayarlanmış mevcut sistem tarihini temsil eder.
ve
DateTime.Now mevcut sistem tarihini ve saatini temsil eder
(v=VS.100)
,.
Bu bağlantıları eklemeyi düşündüm -
Orijinal soruya dönersek, Reflektör kullanarak koddaki farkı açıkladım
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.Today
olduğu DateTime.Now
sıfıra ayarlanmış zamanla.
1 Ocak gece yarısından bu yana geçen onay işaretlerinin sayısını temsil eden bir DateTime değeri ile bir tarih ve saat değerini ifade eden bu DateTime değerinin dize gösterimi arasında bir fark olduğuna dikkat etmek önemlidir. kültüre özgü biçim: https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks
.net tarafından depolanan gerçek zamandır (esasen UTC saati), geri kalanı yalnızca temsillerdir (görüntüleme amaçları için önemlidir).
Eğer Kind
bir özelliktir DateTimeKind.Local
bu örtük yerel bilgisayarın saat dilimi bilgilerini içerir. .Net web hizmeti üzerinden gönderirken, DateTime değerleri varsayılan olarak saat dilimi bilgileriyle birlikte serileştirilir, ör. 2008-10-31T15: 07: 38.6875000-05: 00 ve başka bir saat dilimindeki bir bilgisayar hala saatin tam olarak ne olduğunu bilebilir başvuruluyor.
Yani, DateTime.Now ve DateTime.Today kullanmak mükemmel bir şekilde tamam.
Dize gösterimini gerçek değerle karıştırmaya başladığınızda ve bozuk olmadığı zaman DateTime'ı "düzeltmeye" çalıştığınızda genellikle sorun yaşarsınız.
DateTime.UtcNow
yerine kullanımı ne olacakDateTimeOffset.Now
?