DateTimeOffset
은 순간 시간 ( 절대 시간 이라고도 함)을 나타냅니다 . 즉, 나는 모든 사람에게 보편적 인 순간을 의미합니다 ( 윤초 또는 시간 팽창 의 상대 론적 영향을 설명하지 않음 ). 순간적인 시간을 나타내는 또 다른 방법은 DateTime
where .Kind
입니다 DateTimeKind.Utc
.
이것은 다른 사람의 달력에있는 위치 인 달력 시간 ( 민간 시간 이라고도 함 )과 다르며 전 세계에 많은 다른 달력이 있습니다. 우리는이 달력 시간대를 호출 합니다 . 일정 시간은로 표현되는 DateTime
곳 .Kind
이다 DateTimeKind.Unspecified
, 또는 DateTimeKind.Local
. 그리고 .Local
당신이 결과를 사용하는 컴퓨터가 위치한 곳의 묵시적 이해 시나리오에서만 의미가 있습니다. (예를 들어, 사용자의 워크 스테이션)
그렇다면 왜 DateTimeOffset
UTC 대신에 DateTime
? 그것은 관점에 관한 것입니다. 비유를 사용합시다 – 우리는 사진 작가 인 것처럼 가장 할 것입니다.
캘린더 타임 라인에 서 있고, 당신 앞에 배치 된 순간 타임 라인에있는 사람을 카메라로 향하고 있다고 상상해보십시오. 일광 절약 시간제 또는 표준 시간대의 법적 정의에 대한 기타 변경으로 인해 시간대 규칙에 따라 카메라를 정렬합니다. (손이 안정적이지 않아 카메라가 흔들립니다.)
사진에 서있는 사람은 카메라의 각도를 볼 수 있습니다. 다른 사람들이 사진을 찍는 경우 다른 각도에서 촬영할 수 있습니다. 이것이 Offset
부분의 DateTimeOffset
대표입니다.
따라서 카메라에 "동부 표준시"라고 레이블을 지정하면 때로는 -5를 가리키고 때로는 -4를 가리 킵니다. 전 세계에 카메라가 있으며, 모두 다른 라벨이 붙어 있으며, 다른 각도에서 동일한 순간 타임 라인을 가리키는 카메라가 있습니다. 그들 중 일부는 서로 바로 옆에 (또는 위에) 있기 때문에 오프셋을 아는 것만으로는 시간과 관련된 시간대를 결정하기에 충분하지 않습니다.
그리고 UTC는 어떻습니까? 글쎄, 그것은 손이 안정적으로 보장되는 카메라 중 하나입니다. 삼각대에 있고 땅에 단단히 고정되어 있습니다. 아무데도 안가 우리는 그것의 원근 각도를 제로 오프셋이라고 부릅니다.
그렇다면이 비유는 무엇을 말해줍니까? 직관적 인 지침을 제공합니다.
특정 장소를 기준으로 시간을 나타내는 경우 달력 시간으로 a를 사용하여 나타내십시오 DateTime
. 한 캘린더를 다른 캘린더와 혼동하지 마십시오. Unspecified
당신의 가정이되어야합니다. Local
에서 오는 경우에만 유용합니다 DateTime.Now
. 예를 들어 DateTime.Now
데이터베이스에 가져 와서 저장할 수는 있지만 검색 할 때는 데이터베이스가이라고 가정해야합니다 Unspecified
. 로컬 캘린더가 원래 가져온 캘린더와 동일한 캘린더에 의존 할 수 없습니다.
항상 확실해야하는 경우, 즉시 시간을 나타내는 지 확인하십시오. DateTimeOffset
이를 적용하거나 DateTime
규칙에 따라 UTC 를 사용하십시오 .
순간의 순간을 추적해야하지만 "사용자가 현지 캘린더의 시간을 생각한 시간"을 알고 싶을 경우 - 당신은 해야한다 를 사용합니다 DateTimeOffset
. 이것은 기술 및 법적 문제와 같은 시간 관리 시스템에 매우 중요합니다.
이전에 기록한 레코드를 수정해야하는 경우 DateTimeOffset
새 오프셋이 여전히 사용자와 관련이있을만큼 오프셋에 충분한 정보가 없습니다. 시간대 식별자 도 저장 해야합니다 (생각-위치가 변경된 경우에도 새 사진을 찍을 수 있도록 카메라 이름이 필요함).
또한 .Net 기본 클래스 라이브러리에는 유사한 것이없는 반면, Noda Time 은 이에 대한 표현을 가지고 있음을 지적해야합니다 ZonedDateTime
. a DateTimeOffset
와 TimeZoneInfo.Id
값을 모두 저장해야 합니다.
때때로, 당신은 "누구든지 그것을보고있는"현지인 달력 시간을 나타내기를 원할 것입니다. 예를 들어 오늘의 의미를 정의 할 때 오늘은 항상 자정부터 자정이지만, 이는 순간 타임 라인에서 거의 무한한 수의 겹치는 범위를 나타냅니다. (실제로 시간대는 한정되어 있지만 틱까지 오프셋을 표시 할 수 있습니다.) 이러한 상황에서 "누가 묻는 사람"을 제한하는지 이해해야합니다. 단일 시간대로 질문하거나 적절한 순간으로 다시 변환하는 것을 처리합니다.
다음은 DateTimeOffset
이 비유를 뒷받침 하는 몇 가지 다른 내용 과 똑바로 유지하기위한 몇 가지 팁입니다.
두 DateTimeOffset
값 을 비교하면 비교 하기 전에 먼저 0 오프셋으로 정규화됩니다. 즉, 2012-01-01T00:00:00+00:00
과 2012-01-01T02:00:00+02:00
같은 순간 순간 참조 그러므로 동등하다.
당신이 어떤 단위 테스트와 필요를 수행하는 경우, 오프셋 (offset) 테스트를 확신 할 수 있습니다 모두DateTimeOffset
값과 .Offset
별도로 속성입니다.
.Net 프레임 워크에 내장 된 단방향 암시 적 변환이 DateTime
있어 DateTimeOffset
매개 변수 또는 변수에 전달할 수 있습니다 . 그렇게되면, 이 .Kind
중요 . UTC 종류를 전달하면 오프셋이 0으로 전달되지만 .Local
또는 을 전달하면 local로.Unspecified
간주됩니다 . 프레임 워크는 기본적으로 "음, 당신은 나에게 달력 시간을 순간 시간으로 변환하라고 요청했지만, 이것이 어디에서 왔는지 전혀 모른다. 그래서 나는 단지 로컬 달력을 사용할 것이다." 다른 시간대의 컴퓨터에 지정되지 않은 컴퓨터 를로드하는 경우 큰 문제 입니다. (IMHO-예외가 발생해야하지만 그렇지 않습니다.)DateTime
뻔뻔한 플러그 :
많은 사람들이이 비유가 매우 귀중하다는 것을 나와 함께 나누었습니다. 그래서 나는 이것을 Pluralsight 코스, 날짜 및 시간 기초에 포함 시켰습니다 . "Calendar Time vs. Instantaneous Time"클립의 두 번째 모듈 인 "Context Matters"에서 카메라의 비유를 단계별로 살펴 봅니다.