DateTime 대 DateTimeOffset
현재 우리는 TimeZone 인식 방식으로 .net DateTimes를 처리하는 표준 방법을 가지고 있습니다. 우리가를 생성 할 때마다 DateTime
(예 :를 사용하여 DateTime.UtcNow
) UTC로 수행하고 표시 할 때마다 UTC에서 사용자의 현지 시간으로 다시 변환합니다.
잘 작동하지만 DateTimeOffset
객체 자체에서 로컬 및 UTC 시간을 캡처하는 방법 에 대해 읽었 습니다. 그래서 질문은 DateTimeOffset
우리가 이미 해왔 던 것에 비해 사용의 장점은 무엇일까요?
DateTimeOffset
순간 시간 ( 절대 시간 이라고도 함)을 나타냅니다 . 즉, 모든 사람에게 보편적 인 시간을 의미합니다 ( 윤초 또는 시간 확장 의 상대 론적 효과를 고려하지 않음 ). 순간 시간을 나타내는 또 다른 방법은 DateTime
where .Kind
is DateTimeKind.Utc
입니다.
이 구별되는 일정 시간 (로도 알려져 상용시 다른 사람의 일정에 위치이다), 그리고 많은 다른 달력은 전 세계에 걸쳐있다. 이러한 캘린더를 시간대라고합니다 . 달력 시간은 DateTime
where .Kind
가 DateTimeKind.Unspecified
또는로 표시 DateTimeKind.Local
됩니다. 그리고 .Local
당신이 결과를 사용하는 컴퓨터가 위치한 곳의 묵시적 이해 시나리오에서만 의미가 있습니다. (예 : 사용자의 워크 스테이션)
그렇다면 왜 DateTimeOffset
UTC 대신에 DateTime
? 그것은 모두 관점에 관한 것입니다. 비유를 사용합시다-우리는 사진 가인 척 할 것입니다.
달력 타임 라인에 서서 카메라가 당신 앞에 배치 된 순간 타임 라인에있는 사람을 가리키고 있다고 상상해보십시오. 일광 절약 시간으로 인해 또는 시간대의 법적 정의에 대한 기타 변경으로 인해 주기적으로 변경되는 시간대의 규칙에 따라 카메라를 정렬합니다. (손이 흔들리지 않아 카메라가 흔들립니다.)
사진에 서있는 사람은 카메라가 나오는 각도를 볼 수 있습니다. 다른 사람들이 사진을 찍는다면 다른 각도에서 찍을 수 있습니다. 이것은의 Offset
일부가 DateTimeOffset
나타내는 것입니다.
따라서 카메라에 "동부 시간"이라는 레이블을 지정하면 때로는 -5에서 가리키고 때로는 -4에서 가리키고 있습니다. 전 세계에 카메라가 있고 모두 서로 다른 레이블이 지정되어 있으며 모두 다른 각도에서 동일한 순간 타임 라인을 가리키고 있습니다. 그들 중 일부는 서로 바로 옆에 (또는 위에) 있으므로 오프셋을 아는 것만으로는 시간이 관련된 시간대를 결정하는 데 충분하지 않습니다.
그리고 UTC는 어떻습니까? 글쎄, 그것은 안정적인 손을 보장하는 하나의 카메라입니다. 삼각대에 있고 땅에 단단히 고정되어 있습니다. 아무데도 가지 않습니다. 우리는 원근 각을 제로 오프셋이라고 부릅니다.
그래서-이 비유는 우리에게 무엇을 말합니까? 직관적 인 지침을 제공합니다.
If you are representing time relative to some place in particular, represent it in calendar time with a
DateTime
. Just be sure you don't ever confuse one calendar with another.Unspecified
should be your assumption.Local
is only useful coming fromDateTime.Now
. For example, I might getDateTime.Now
and save it in a database - but when I retrieve it, I have to assume that it isUnspecified
. I can't rely that my local calendar is the same calendar that it was originally taken from.If you must always be certain of the moment, make sure you are representing instantaneous time. Use
DateTimeOffset
to enforce it, or use UTCDateTime
by convention.If you need to track a moment of instantaneous time, but you want to also know "What time did the user think it was on their local calendar?" - then you must use a
DateTimeOffset
. This is very important for timekeeping systems, for example - both for technical and legal concerns.If you ever need to modify a previously recorded
DateTimeOffset
- you don't have enough information in the offset alone to ensure that the new offset is still relevant for the user. You must also store a timezone identifier (think - I need the name of that camera so I can take a new picture even if the position has changed).It should also be pointed out that Noda Time has a representation called
ZonedDateTime
for this, while the .Net base class library does not have anything similar. You would need to store both aDateTimeOffset
and aTimeZoneInfo.Id
value.Occasionally, you will want to represent a calendar time that is local to "whomever is looking at it". For example, when defining what today means. Today is always midnight to midnight, but these represent a near-infinite number of overlapping ranges on the instantaneous timeline. (In practice we have a finite number of timezones, but you can express offsets down to the tick) So in these situations, make sure you understand how to either limit the "who's asking?" question down to a single time zone, or deal with translating them back to instantaneous time as appropriate.
Here are a few other little bits about DateTimeOffset
that back up this analogy, and some tips for keeping it straight:
If you compare two
DateTimeOffset
values, they are first normalized to zero offset before comparing. In other words,2012-01-01T00:00:00+00:00
and2012-01-01T02:00:00+02:00
refer to the same instantaneous moment, and are therefore equivalent.If you are doing any unit testing and need to be certain of the offset, test both the
DateTimeOffset
value, and the.Offset
property separately.There is a one-way implicit conversion built in to the .Net framework that lets you pass a
DateTime
into anyDateTimeOffset
parameter or variable. When doing so, the.Kind
matters. If you pass a UTC kind, it will carry in with a zero offset, but if you pass either.Local
or.Unspecified
, it will assume to be local. The framework is basically saying, "Well, you asked me to convert calendar time to instantaneous time, but I have no idea where this came from, so I'm just going to use the local calendar." This is a huge gotcha if you load up an unspecifiedDateTime
on a computer with a different timezone. (IMHO - that should throw an exception - but it doesn't.)
Shameless Plug:
Many people have shared with me that they find this analogy extremely valuable, so I included it in my Pluralsight course, Date and Time Fundamentals. You'll find a step-by-step walkthrough of the camera analogy in the second module, "Context Matters", in the clip titled "Calendar Time vs. Instantaneous Time".
From Microsoft:
These uses for DateTimeOffset values are much more common than those for DateTime values. As a result, DateTimeOffset should be considered the default date and time type for application development.
source: "Choosing Between DateTime, DateTimeOffset, TimeSpan, and TimeZoneInfo", MSDN
We use DateTimeOffset
for nearly everything as our application deals with particular points in time (e.g. when a record was created/updated). As a side note, we use DATETIMEOFFSET
in SQL Server 2008 as well.
I see DateTime
as being useful when you want to deal with dates only, times only, or deal with either in a generic sense. For example, if you have an alarm that you want to go off every day at 7 am, you could store that in a DateTime
utilizing a DateTimeKind
of Unspecified
because you want it to go off at 7am regardless of DST. But if you want to represent the history of alarm occurrences, you would use DateTimeOffset
.
Use caution when using a mix of DateTimeOffset
and DateTime
especially when assigning and comparing between the types. Also, only compare DateTime
instances that are the same DateTimeKind
because DateTime
ignores timezone offset when comparing.
DateTime is capable of storing only two distinct times, the local time and UTC. The Kind property indicates which.
DateTimeOffset expands on this by being able to store local times from anywhere in the world. It also stores the offset between that local time and UTC. Note how DateTime cannot do this unless you'd add an extra member to your class to store that UTC offset. Or only ever work with UTC. Which in itself is a fine idea btw.
There's a few places where DateTimeOffset
makes sense. One is when you're dealing with recurring events and daylight savings time. Let's say I want to set an alarm to go off at 9am every day. If I use the "store as UTC, display as local time" rule, then the alarm will be going off at a different time when daylight savings time is in effect.
There are probably others, but the above example is actually one that I've run into in the past (this was before the addition of DateTimeOffset
to the BCL - my solution at the time was to explicitly store the time in the local timezone, and save the timezone information along side it: basically what DateTimeOffset
does internally).
The most important distinction is that DateTime does not store time zone information, while DateTimeOffset does.
Although DateTime distinguishes between UTC and Local, there is absolutely no explicit time zone offset associated with it. If you do any kind of serialization or conversion, the server's time zone is going to be used. Even if you manually create a local time by adding minutes to offset a UTC time, you can still get bit in the serialization step, because (due to lack of any explicit offset in DateTime) it will use the server's time zone offset.
For example, if you serialize a DateTime value with Kind=Local using Json.Net and an ISO date format, you'll get a string like 2015-08-05T07:00:00-04
. Notice that last part (-04) had nothing to do with your DateTime or any offset you used to calculate it... it's just purely the server's time zone offset.
Meanwhile, DateTimeOffset explicitly includes the offset. It may not include the name of the time zone, but at least it includes the offset, and if you serialize it, you're going to get the explicitly included offset in your value instead of whatever the server's local time happens to be.
Most of the answers are good , but i thought of adding some more links of MSDN for more information
- A brief History of DateTime - By Anthony Moore by BCL team
- Choosing between Datetime and DateTime Offset - by MSDN
- Do not forget SQL server 2008 onwards has a new Datatype as DateTimeOffset
- The .NET Framework includes the DateTime, DateTimeOffset, and TimeZoneInfo types, all of which can be used to build applications that work with dates and times.
- Performing Arithmetic Operations with Dates and Times-MSDN
A major difference is that DateTimeOffset
can be used in conjunction with TimeZoneInfo
to convert to local times in timezones other than the current one.
This is useful on a server application (e.g. ASP.NET) that is accessed by users in different timezones.
This piece of code from Microsoft explains everything:
// Find difference between Date.Now and Date.UtcNow
date1 = DateTime.Now;
date2 = DateTime.UtcNow;
difference = date1 - date2;
Console.WriteLine("{0} - {1} = {2}", date1, date2, difference);
// Find difference between Now and UtcNow using DateTimeOffset
dateOffset1 = DateTimeOffset.Now;
dateOffset2 = DateTimeOffset.UtcNow;
difference = dateOffset1 - dateOffset2;
Console.WriteLine("{0} - {1} = {2}",
dateOffset1, dateOffset2, difference);
// If run in the Pacific Standard time zone on 4/2/2007, the example
// displays the following output to the console:
// 4/2/2007 7:23:57 PM - 4/3/2007 2:23:57 AM = -07:00:00
// 4/2/2007 7:23:57 PM -07:00 - 4/3/2007 2:23:57 AM +00:00 = 00:00:00
The only negative side of DateTimeOffset I see is that Microsoft "forgot" (by design) to support it in their XmlSerializer class. But it has since been added to the XmlConvert utility class.
I say go ahead and use DateTimeOffset and TimeZoneInfo because of all the benefits, just beware when creating entities which will or may be serialized to or from XML (all business objects then).
참고 URL : https://stackoverflow.com/questions/4331189/datetime-vs-datetimeoffset
'Programing' 카테고리의 다른 글
Java를 사용하여 문자열을 텍스트 파일에 어떻게 저장합니까? (0) | 2020.10.02 |
---|---|
bash에서 문자열이 어떤 값으로 시작하는지 어떻게 확인할 수 있습니까? (0) | 2020.10.02 |
Java Vector (및 Stack) 클래스가 더 이상 사용되지 않거나 더 이상 사용되지 않는 것으로 간주되는 이유는 무엇입니까? (0) | 2020.10.02 |
R에서 "="와 "<-"할당 연산자의 차이점은 무엇입니까? (0) | 2020.10.02 |
"병합하기 전에 변경 사항을 커밋하거나 숨길 수 있습니다"라고 말하는 git을 어떻게 해결합니까? (0) | 2020.10.02 |