답변:
DateTime.Now
DateTime
코드가 실행되는 컴퓨터의 현지 날짜와 시간으로 구성된 값을 반환합니다 . 그것은있다 DateTimeKind.Local
자사에 할당 된 Kind
속성입니다. 다음 중 하나를 호출하는 것과 같습니다.
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
DateTime
위의 표현식 중 하나와 동일한 연도, 월 및 일 구성 요소를 갖지만 시간 구성 요소가 0으로 설정된 값을 리턴합니다 . 또한이 DateTimeKind.Local
자사의 Kind
속성입니다. 다음 중 하나에 해당합니다.
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
내부적으로 시스템 시계는 UTC로 표시되므로 호출 DateTime.Now
하면 먼저 GetSystemTimeAsFileTime
Win32 API 의 함수를 통해 UTC 시간을 얻은 다음 값을 현지 시간대로 변환합니다. (따라서 DateTime.Now.ToUniversalTime()
보다 비싸다 DateTime.UtcNow
.)
또한와 DateTimeOffset.Now.DateTime
비슷한 값을 DateTime.Now
갖지만 DateTimeKind.Unspecified
그보다는 DateTimeKind.Local
- 값을 가지 므로 다른 작업으로 인해 다른 오류가 발생할 수 있습니다.
그래서, 대답은 간단 즉 DateTime.Today
동일합니다 DateTime.Now.Date
.
그러나 IMHO-이 중 하나 또는 위와 동등한 것을 사용해서는 안됩니다.
를 요청 DateTime.Now
하면 코드가 실행되는 컴퓨터의 로컬 달력 시계 값을 묻습니다. 그러나 당신이 얻는 것은 그 시계에 대한 정보가 없습니다! 당신이 얻는 가장 좋은 것입니다 DateTime.Now.Kind == DateTimeKind.Local
. 그러나 누구의 지역입니까? 데이터베이스에 저장하거나 화면에 표시하거나 웹 서비스를 사용하여 전송하는 등 값이있는 작업을 수행하면 해당 정보가 손실됩니다.
현지 시간대가 일광 절약 규칙을 준수하는 경우 해당 정보를에서 가져올 수 없습니다 DateTime.Now
. "대체"전환과 같이 모호한 시간에 두 가능한 순간 중 어느 것이로 검색 한 값에 해당하는지 알 수 없습니다 DateTime.Now
. 예를 들어, 시스템 시간대가로 설정되어 Mountain Time (US & Canada)
있고 DateTime.Now
2013 년 11 월 3 일 초에 요청 2013-11-03 01:00:00
한다고 가정 합니다. 결과 는 무엇을 의미합니까? 동일한 달력 날짜 시간으로 표시되는 두 순간의 순간이 있습니다. 이 값을 다른 사람에게 보내면 그들이 어떤 의미인지 알 수 없습니다. 특히 규칙이 다른 시간대에있는 경우.
가장 좋은 방법은 DateTimeOffset
대신 사용하는 것입니다.
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
위에서 설명한 동일한 시나리오 2013-11-03 01:00:00 -0600
에서 전환 전 또는 2013-11-03 01:00:00 -0700
전환 후 값을 얻습니다 . 이 값을 보는 사람은 내가 의미하는 바를 알 수 있습니다.
이 주제에 대한 블로그 게시물을 작성했습니다. DateTime.Now에 대한 사례를 읽어보십시오 .
또한이 봄에는 "봄을 향한"전환이 정확히 자정에 이루어지는 곳이 있습니다 (예 : 브라질). 시계는 23:59에서 01:00로 이동합니다. 이는 DateTime.Today
해당 날짜에 얻은 가치 가 존재하지 않음을 의미합니다! 을 사용하더라도 DateTimeOffset.Now.Date
동일한 결과가 나타나고 여전히이 문제가 있습니다. 전통적 Date
으로 .Net 에는 객체 와 같은 것이 없었기 때문 입니다. 따라서 값을 얻는 방법에 관계없이 일단 시간을 없앤 후에는 실제로 "자정"을 나타내는 것이 아니라는 점을 명심해야합니다.
이 문제에 대한 완벽한 해결책을 원한다면 NodaTime 을 사용하는 것이 가장 좋습니다 . LocalDate
클래스는 제대로 한 번하지 않고 날짜를 나타냅니다. 로컬 시스템 시간대를 포함하여 모든 시간대의 현재 날짜를 얻을 수 있습니다.
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을 사용하지 않으려면 다른 옵션이 있습니다. 날짜 전용 개체의 구현을 .Net CoreFX Lab 프로젝트에 기여 했습니다. System.Time
MyGet 피드에서 패키지 개체를 찾을 수 있습니다 . 프로젝트에 추가되면 다음 중 하나를 수행 할 수 있습니다.
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
DateTime.UtcNow
애플리케이션 또는 사양에서 값이 UTC로 전달 될 수있는 경우 허용됩니다. (실제로 필드 또는 속성 MyDateUtc
을 그냥 대신 호출하는 것이 좋습니다. MyDate
하지만 케이크 위에 착빙하는 것입니다.) 스펙 또는 필드 이름으로 전달할 수없는 경우 DateTimeOffset.UtcNow
0 오프셋을 전달하는 데 사용할 수 있습니다 날짜 및 시간 값과 함께.
DateTime.Now.Date
.
(v=VS.100)
.
이 링크 추가를 생각했습니다-
Reflector를 사용하여 원래의 질문으로 돌아가서 코드의 차이점을 설명했습니다.
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
이다 DateTime.Now
제로로 설정 시간.
0000 년 1 월 1 일 자정 이후 경과 된 틱 수를 나타내는 DateTime 값과 DateTime 값의 문자열 표현 (예 : 문화 별 형식 : https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks
그물에 저장된 실제 시간 (기본적으로 UTC 시간)이며, 나머지는 단지입니다 표현 (표시 목적으로 중요하다).
경우 Kind
속성입니다 DateTimeKind.Local
그것은 암시 적으로 로컬 컴퓨터의 시간대 정보가 포함되어 있습니다. .net 웹 서비스를 통해 전송할 때 기본적으로 DateTime 값은 표준 시간대 정보 (예 : 2008-10-31T15 : 07 : 38.6875000-05 : 00)와 함께 직렬화되며 다른 시간대의 컴퓨터는 여전히 어떤 시간인지 알 수 있습니다 참조되고 있습니다.
따라서 DateTime.Now 및 DateTime.Today를 사용하는 것은 완벽합니다.
일반적으로 문자열 표현을 실제 값과 혼동하기 시작하고 DateTime이 손상되지 않은 경우 "고정"하려고 할 때 문제가 발생하기 시작합니다.
DateTime.UtcNow
대신에 사용 하는 것은DateTimeOffset.Now
어떻습니까?