System.DateTime.Now와 System.DateTime.Today의 차이점


127

사람 사이의 차이를 설명 할 수 System.DateTime.NowSystem.DateTime.TodayC # .NET에서를? 가능하다면 각각의 장단점.

답변:


179

DateTime.NowDateTime코드가 실행되는 컴퓨터의 현지 날짜와 시간으로 구성된 값을 반환합니다 . 그것은있다 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.TodayDateTime위의 표현식 중 하나와 동일한 연도, 월 및 일 구성 요소를 갖지만 시간 구성 요소가 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하면 먼저 GetSystemTimeAsFileTimeWin32 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.Now2013 년 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.TimeMyGet 피드에서 패키지 개체를 찾을 수 있습니다 . 프로젝트에 추가되면 다음 중 하나를 수행 할 수 있습니다.

using System;
...

Date localDate = Date.Today;

Date utcDate = Date.UtcToday;

Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);

9
DateTime.UtcNow대신에 사용 하는 것은 DateTimeOffset.Now어떻습니까?
Samuel Liew

5
DateTime.UtcNow애플리케이션 또는 사양에서 값이 UTC로 전달 될 수있는 경우 허용됩니다. (실제로 필드 또는 속성 MyDateUtc을 그냥 대신 호출하는 것이 좋습니다. MyDate하지만 케이크 위에 착빙하는 것입니다.) 스펙 또는 필드 이름으로 전달할 수없는 경우 DateTimeOffset.UtcNow0 오프셋을 전달하는 데 사용할 수 있습니다 날짜 및 시간 값과 함께.
Matt Johnson-Pint

그들은 평등하지 않습니다. 오늘 시간은 00:00:00입니다.
James Wilkins

@JamesWilkins-무엇을 받고 있는지 잘 모르겠습니다. 그렇습니다 DateTime.Now.Date.
Matt Johnson-Pint

@MattJohnson 질문은 DateTime.Today와 DateTime.Now.Date가 아니라 DateTime.Today와 DateTime.Now의 차이점을 묻습니다.
David Anderson

85

시각. .Now09:23:12 또는 무엇이든 포함; .Today날짜 부분 만 해당됩니다 (당일 00:00:00).

그래서 사용 .Now당신이 시간을 포함 할 경우, 그리고 .Today당신은 단지 날짜를 원한다면!

.Today 본질적으로 .Now.Date


27
... 시스템 현지 시간대 UtcNow정말로 원하지 않는 한 사용하십시오 . (특히, 거의 항상 잘못된 선택 인 웹 앱에서)
Jon Skeet

22

DateTime.Now속성은 현재 날짜와 시간을 반환합니다 (예 :) 2011-07-01 10:09.45310.

DateTime.Today속성은 시간 구성 요소가 0으로 설정된 현재 날짜를 반환합니다 2011-07-01 00:00.00000.

DateTime.Today속성은 실제로 다음을 반환하도록 구현됩니다 DateTime.Now.Date.

public static DateTime Today {
  get {
    DateTime now = DateTime.Now;
    return now.Date;
  }
}

9

DateTime.Today 는 시간 부분이 00:00:00으로 설정된 현재 시스템 날짜를 나타냅니다.

DateTime.Now 는 현재 시스템 날짜 및 시간을 나타냅니다.


2
단지 관찰 ... 1.1 문서는 4.0 문서보다 훨씬 덜 상세합니다. vLatest에 연결하는 것이 좋습니다?
Marc Gravell

3
@megaperlz : 이제 vLatest가 아닌 4.0에 연결되었습니다. 를 삭제하면 VLatest 링크를 만들 수 있습니다 (v=VS.100).
Brian

6

이 링크 추가를 생각했습니다-

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);
          }
        }

5
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

1

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이 손상되지 않은 경우 "고정"하려고 할 때 문제가 발생하기 시작합니다.


-1

DateTime.Now.ToShortDateString() 날짜 부분 만 표시합니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.