Programing

DateTime 대 DateTimeOffset

lottogame 2020. 10. 2. 21:23
반응형

DateTime 대 DateTimeOffset


현재 우리는 TimeZone 인식 방식으로 .net DateTimes를 처리하는 표준 방법을 가지고 있습니다. 우리가를 생성 할 때마다 DateTime(예 :를 사용하여 DateTime.UtcNow) UTC로 수행하고 표시 할 때마다 UTC에서 사용자의 현지 시간으로 다시 변환합니다.

잘 작동하지만 DateTimeOffset객체 자체에서 로컬 및 UTC 시간을 캡처하는 방법 에 대해 읽었 습니다. 그래서 질문은 DateTimeOffset우리가 이미 해왔 던 것에 비해 사용의 장점은 무엇일까요?


DateTimeOffset순간 시간 ( 절대 시간 이라고도 함)을 나타냅니다 . 즉, 모든 사람에게 보편적 인 시간을 의미합니다 ( 윤초 또는 시간 확장 의 상대 론적 효과를 고려하지 않음 ). 순간 시간을 나타내는 또 다른 방법은 DateTimewhere .Kindis DateTimeKind.Utc입니다.

이 구별되는 일정 시간 (로도 알려져 상용시 다른 사람의 일정에 위치이다), 그리고 많은 다른 달력은 전 세계에 걸쳐있다. 이러한 캘린더를 시간대라고합니다 . 달력 시간은 DateTimewhere .KindDateTimeKind.Unspecified또는로 표시 DateTimeKind.Local됩니다. 그리고 .Local당신이 결과를 사용하는 컴퓨터가 위치한 곳의 묵시적 이해 시나리오에서만 의미가 있습니다. (예 : 사용자의 워크 스테이션)

그렇다면 왜 DateTimeOffsetUTC 대신에 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 from DateTime.Now. For example, I might get DateTime.Now and save it in a database - but when I retrieve it, I have to assume that it is Unspecified. 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 UTC DateTime 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 a DateTimeOffset and a TimeZoneInfo.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 and 2012-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 any DateTimeOffset 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 unspecified DateTime 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 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.

XmlConvert.ToDateTimeOffset

XmlConvert.ToString

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

반응형