DateTime (UTC) 저장과 DateTimeOffset 저장


94

일반적으로 데이터베이스에서 읽고 쓰기 직전에 DateTime 변환 (UTC에서 현지 시간으로, 현지 시간에서 UTC로)을 수행하는 "인터셉터"가 있으므로 DateTime.Now걱정하지 않고 시스템 전체에서 (파생 및 비교) 사용할 수 있습니다. 시간대에 대해.

직렬화 및 컴퓨터 간 데이터 이동과 관련하여 날짜 시간은 항상 UTC이므로 귀찮게 할 필요가 없습니다.

날짜 (SQL 2008-datetime)를 UTC 형식으로 계속 저장해야합니까, 아니면 대신 DateTimeOffset(SQL 2008-datetimeoffset)을 사용하여 저장해야 합니까?

데이터베이스의 UTC 날짜 (datetime 유형)가 오랫동안 작동하고 알려져 왔는데 왜 변경합니까? 장점은 무엇입니까?

이미 같은 기사로 보았다 이 하나 ,하지만 난 100 % 비록 확신 해요. 이견있는 사람?



1
참고 항목 : DateTime 대 DateTimeOffset-.Net 용으로 작성되었지만 개념적으로 SQL에도 적용됩니다.
Matt Johnson-Pint 2014

답변:


131

UTC만으로는 사용할 수없는 큰 차이가 있습니다.

  • 이와 같은 시나리오가 있다면

    • 하나의 서버여러 클라이언트 (모두 지리적으로 다른 시간대에 있음 )
    • 클라이언트는 날짜 시간 정보로 일부 데이터를 생성합니다.
    • 클라이언트는 모든 것을 중앙 서버에 저장합니다.
  • 그때:

    • datetimeoffset은 클라이언트의 현지 시간과 UTC 시간의 오프셋 을 저장합니다.
    • 모든 클라이언트는 모든 데이터의 UTC 시간과 정보가 생성 된 장소의 현지 시간을 알고 있습니다.
  • 그러나:

    • UTC datetime은 UTC datetime 만 저장 하므로 데이터가 시작된 클라이언트 위치의 현지 시간에 대한 정보가 없습니다.
    • 다른 클라이언트는 날짜 시간 정보가 나온 장소의 현지 시간을 모릅니다.
    • 다른 클라이언트는 데이터가 생성 된 클라이언트의 현지 시간이 아닌 데이터베이스 (UTC 시간 사용)에서 현지 시간 만 계산할 수 있습니다.

간단한 예는 항공권 예약 시스템입니다. 항공권에는 2 회가 포함되어야합니다.- "이륙"시간 ( "출발지"도시 시간대)- "착륙"시간 ( "목적지"도시 시간대)


2
이것이 적절한시기에 대해 읽은 가장 좋은 설명이며, 우리에게는 많은 것을 읽었습니다. 외부 데이터에 대한 시간을 UTC로 가져오고 필요한 경우 다른 소스에서 위치를 알고 있습니다. 그렇게 분명하게 보이게 해주셔서 감사합니다.
Andrew Backer 2012 년

19
"datetimeoffset은 UTC 시간을 저장하고 클라이언트의 로컬 시간에 대한 오프셋도 저장합니다"라고 말했지만 datetimeoffset은 LOCAL 시간 + 오프셋 또는 UTC 시간 + 오프셋을 +0과 동일하게 저장합니다.
Serhii Kyslyi 2011

DT 기반이 UTC이기 때문에 DTO를 DT로 캐스트 할 수는 있지만 (이는 데이터베이스를 사용하는 모든 사용자에게 추가 단계이며 UTC 시간 만 사용하는 것보다 더 간단하지 않습니다)
iliketocode

2
DateTmeOffset은 "UTC 시간 및 UTC 오프셋"이 아닌 "현지 시간 및 UTC 오프셋"을 저장하는 것과 비슷합니다. datetime으로 캐스트하거나 datepart 함수를 사용하는 경우 로컬 날짜 및 시간 구성 요소를 가져옵니다.
Triynko

" 모든 클라이언트는 모든 데이터의 UTC 시간과 정보가 발생한 장소의 현지 시간을 알고 있습니다." 날짜 필드의 일부로 저장하는 것은이 경우에 비정규 화 된 느낌이 들지만. 유스 케이스는 무엇입니까? 즉, UTC를 사용하지 않고 오프셋을 InputLocationId(또는 유사한 정규화 된 엔티티)로 가져 오지 않는 이유입니다 . 계산이 필요하지만 (안녕하세요, 예외 ... 특히 인디애나 ) 여전히 결정적인 프로세스이며 앱의 날짜 시간 논리의 균형은 간단합니다.
ruffin

23

모든 역사적 시간에 대해 UTC를 사용하는 것이 절대적으로 정확합니다 (즉, 기록 이벤트 발생). UTC에서 현지 시간으로 이동하는 것은 항상 가능하지만 항상 그 반대는 아닙니다.

현지 시간은 언제 사용합니까? 이 질문에 대답하세요:

정부가 갑자기 일광 절약 시간제를 변경하기로 결정한 경우이 데이터를 함께 변경 하시겠습니까?

대답이 "예"인 경우에만 현지 시간을 저장하십시오. 분명히 그것은 미래의 날짜에만 해당되며 일반적으로 사람들에게 어떤 식 으로든 영향을 미치는 날짜에만 해당됩니다.

시간대 / 오프셋을 저장하는 이유는 무엇입니까?

첫째, 작업을 수행 한 사용자에 대한 오프셋이 무엇인지 기록하고 싶다면 아마도 그렇게하는 것이 가장 좋을 것입니다. 즉, 로그인 할 때 해당 사용자의 위치와 시간대를 기록하십시오.

둘째, 디스플레이 용으로 변환하려면 해당 시간대에 대한 모든 현지 시간 오프셋 전환 테이블이 있어야합니다. 현재 오프셋만으로는 충분하지 않다는 것만 알면됩니다. 6 개월 전의 날짜 / 시간을 표시하는 경우 오프셋이 다릅니다.


4
Windows UTC에서 현지 시간으로 변환은 과거 날짜의 일광 절약 시간이 변경되는 경우를 고려합니다. 이 경우 현지 시간을 저장하려는 이유를 알 수 없습니다.
Jamiegs 2011 년

1
@Jamiegs Windows는 역사적으로 "마지막 기록 정보"만 알고 있습니다 (.NET DateTime 문서에서 암시 / 노트 됨). 포괄적이지 않습니다.

2
물론 이벤트 위치도 저장해야합니다. 그렇지 않으면 이벤트가 발생한 "현지 시간"에 말할 수 없습니다.
keuleJ

20

DATETIMEOFFSET을 사용하면 한 필드에 현지 시간과 UTC 시간을 저장할 수 있습니다.

이를 통해 어떤 방식 으로든 표시하기 위해 데이터를 처리 할 필요없이 로컬 또는 UTC 시간으로 매우 간단하고 효율적인보고가 가능합니다.

가장 일반적인 두 가지 요구 사항은 로컬 보고서의 경우 현지 시간과 그룹 보고서의 경우 UTC 시간입니다.

현지 시간은 DATETIMEOFFSET의 DATETIME 부분에 저장되고 UTC의 OFFSET은 OFFSET 부분에 저장되므로 변환이 간단하며 데이터가 가져온 시간대를 알 필요가 없으므로 모두 데이터베이스 수준에서 수행 할 수 있습니다. .

시간을 밀리 초로 줄일 필요가없는 경우 (예 : 분 또는 초) DATETIMEOFFSET (0)을 사용할 수 있습니다. 그러면 DATETIMEOFFSET 필드에는 DATETIME과 동일한 8 바이트의 저장 공간 만 필요합니다.

따라서 UTC DATETIME 대신 DATETIMEOFFSET을 사용하면보고에 더 많은 유연성, 효율성 및 단순성을 제공합니다.


너무 나쁜 엔터티 프레임 워크는 datetimeoffset 필드의 로컬 날짜 / 시간에 액세스 할 수있는 방법이 없으므로 특정 로컬 날짜를 쿼리 할 수 ​​없습니다.
Triynko

@ Triynko 당신이 무슨 뜻인지 설명 할 수 있습니까? 예?
reidLinden dec.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.