[c#] C #에서만 날짜 유형-날짜 유형이없는 이유는 무엇입니까?

C # 프로젝트에서는 시간없이 날짜를 표시해야합니다. DateTime의 존재를 알고 있지만 시간도 포함합니다. 특정 변수와 메서드 인수가 날짜 기반임을 명시하고 싶습니다 . 따라서 나는 DateTime.Date속성을 사용할 수 없습니다

이 문제에 대한 표준 접근 방식은 무엇입니까? 확실히 내가 처음으로 이런 일을 겪지는 않습니까? DateC #에 클래스 가없는 이유는 무엇 입니까?

누구든지 구조체를 사용하는 멋진 구현이 있고 DateTime에 대한 일부 확장 방법을 사용하고 == 및 <,>와 같은 일부 연산자를 구현할 수 있습니까?



답변

이 고전적인 질문에 업데이트를 추가 할 수 있습니다.

  • Jon Skeet의 Noda Time 라이브러리는 이제 상당히 성숙되었으며 LocalDate. (이 경우 로컬 은 코드가 실행되는 컴퓨터에 반드시 로컬 일 필요는없는 누군가 에게 로컬을 의미 합니다.)

  • 라는 날짜 전용 형식 Datecorefxlab 프로젝트 를 통해 .NET Core에 제안 된 추가 항목 입니다. 유형 및 기존 유형에 대한 여러 확장 방법 System.Time과 함께 패키지 에서 찾을 수 TimeOfDay있습니다.

이 문제를 많이 연구 했으므로 이러한 유형의 필요성에 대한 몇 가지 이유도 공유하겠습니다.

  1. 날짜 전용 값과 자정 날짜 값 사이에 논리적 불일치가 있습니다.

    • 모든 현지 날 모든 시간대에 자정 있는 것은 아닙니다 . 예 : 브라질의 봄-포워드 일광 절약 시간 전환은 시계를 11:59:59에서 01:00:00으로 이동합니다.

    • 날짜-시간은 항상 하루 내의 특정 시간을 나타내며 날짜 전용은 하루의 시작, 하루의 끝 또는 전체 범위를 나타낼 수 있습니다.

  2. 날짜에 시간을 추가하면 시간대를주의 깊게 관찰하지 않는 경우 값이 한 환경에서 다른 환경으로 전달됨 에 따라 날짜가 변경 될 수 있습니다 . 이것은 일반적으로 JavaScript (그 Date객체가 실제로 날짜 + 시간)에서 발생하지만 .NET에서도 쉽게 발생하거나 JavaScript와 .NET간에 데이터가 전달 될 때 직렬화에서 발생할 수 있습니다.

  3. DateTimeXML 또는 JSON (및 기타)을 사용하여 직렬화하면 중요하지 않더라도 항상 시간이 포함됩니다. 특히 생년월일과 기념일과 같은 것을 고려하면 시간과 무관 한 상황을 고려하면 매우 혼란 스럽습니다.

  4. 구조적으로 DateTimeDDD 가치 객체 이지만 여러 가지 방식으로 책임감 있는 단일 원칙 을 위반합니다 .

    • 날짜 + 시간 유형으로 설계되었지만 종종 날짜 전용 (시간 무시) 또는 시간 전용 (날짜 무시)으로 사용됩니다. ( TimeSpan또한 시간대에도 자주 사용되지만 다른 주제입니다.)

    • DateTimeKind에 부착 된 값 .Kind속성은 세 가지로 하나의 유형을 분할 Unspecified종류가 정말 구조의 원래 의도와 방법 있음을 사용해야합니다. Utc종류 가지런 구체적 UTC 값으로, 상기 Local종류 가지런 환경의 현지 시간대와 값.

      종류에 대해 별도의 플래그를 가진 문제는 당신이 소비 할 때마다이 있다는 것입니다 DateTime, 당신이하는 생각 확인하기 위해 .Kind취할 행동을 결정합니다. 프레임 워크 메소드는 모두이 작업을 수행하지만 다른 메소드는 종종 잊어 버립니다. 유형이 이제 변경해야하는 두 가지 이유 (값 및 종류)가 있으므로 이것은 진정한 SRP 위반입니다.

    • 이 두 가지는 컴파일되지만 종종 무의미하거나 부작용으로 인한 이상한 경계 사례가있는 API 사용으로 이어집니다. 치다:

      // nonsensical, caused by mixing types
      DateTime dt = DateTime.Today - TimeSpan.FromHours(3);  // when on today??
      
      // strange edge cases, caused by impact of Kind
      var london = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
      var paris = TimeZoneInfo.FindSystemTimeZoneById("Romance Standard Time");
      var dt = new DateTime(2016, 3, 27, 2, 0, 0);  // unspecified kind
      var delta = paris.GetUtcOffset(dt) - london.GetUtcOffset(dt);  // side effect!
      Console.WriteLine(delta.TotalHours); // 0, when should be 1 !!!

요약하면 a는 날짜 전용으로 사용할 DateTime 있지만 사용하는 모든 장소에서 시간을 무시하고 UTC 또는 다른 곳으로 변환하지 않도록 매우주의 할 때만 사용해야합니다. 시간대.


답변

나는 Date당신이 이미 DateTime그것을 처리 할 수 있는 것을 가지고 있기 때문에 헌신적 인 순수한 수업 이 없다고 생각 합니다. 갖는 Date중복과 혼란으로 이어질 것입니다.

표준 접근 방식을 원하면 시간 값이 12:00:00 자정 (00:00:00)으로 설정된 DateTime.Date날짜 부분 만 제공 하는 속성을 살펴보십시오 DateTime.


답변

나는 refsrcfeedback@microsoft.com으로 이메일을 보냈고 그것이 그들의 대답입니다.

Marcos, 여기는 이런 질문을하기에 좋은 곳이 아닙니다. http://stackoverflow.com을
시도해보십시오 . 짧은 대답은 특정 시점을 나타내는 모델이 필요하다는 것입니다. DateTime이 그렇게합니다 . 실제로 가장 유용한 시나리오입니다 . 인간이 시점을 표시하기 위해 두 가지 개념 (날짜와 시간)을 사용한다는 사실은 임의적이며 분리하는 데 유용하지 않습니다.

보증되는 곳에서만 분리하고 맹목적으로 일을하기 위해 일을하지 마십시오. 다음과 같이 생각해보십시오. DateTime을 날짜와 시간으로 분할하여 해결되는 문제는 무엇입니까? 그리고 지금 가지고 있지 않은 문제는 무엇입니까? 힌트 : .NET 프레임 워크에서 DateTime 사용을 살펴보면 : http://referencesource.microsoft.com/#mscorlib/system/datetime.cs#df6b1eba7461813b#references
대부분이 메서드에서 반환되고 있음을 알 수 있습니다 . DateTime과 같은 단일 개념이 없다면 매개 변수 또는 튜플을 사용하여 날짜 및 시간 쌍을 반환해야합니다.

HTH, 키릴 오센 코프

내 이메일에서 DateTime이 TimeZoneInfo를 사용하여 기계의 시간을 가져 오기 때문인지 질문했습니다. 그래서 저는 “비즈니스 규칙”이 “너무 결합되어”있기 때문이라고 말하고 싶습니다. 그들은 저에게 그것을 털어 놓았습니다.


답변

시간 부분, 시간대, 로컬 대 utc 등에 대해 걱정하지 않고 간단한 날짜가 필요할 때 간단한 Date 구조체 를 만들었습니다 .

https://github.com/claycephus/csharp-date


답변

날짜 비교를 실행해야하는 경우

yourdatetime.Date;

화면에 표시하는 경우

yourdatetime.ToShortDateString();


답변

추측 해 보겠습니다. SQL Server 2008까지 SQL에 Date 데이터 유형이 없었기 때문에 SQL Server에 저장하기가 어려울 수 있습니다. 그리고 결국 Microsoft 제품입니까?


답변

왜 그런지 아는 사람. .NET 프레임 워크에는 많은 잘못된 디자인 결정이 있습니다. 그러나 이것은 매우 사소한 것이라고 생각합니다. 시간 부분은 항상 무시할 수 있으므로 일부 코드에서 DateTime이 날짜 이상을 참조하도록 결정하더라도 관심있는 코드는 날짜 부분 만 살펴보아야합니다. 또는 날짜 만 나타내는 새 유형을 만들고 DateTime의 함수를 사용하여 무거운 작업 (계산)을 수행 할 수 있습니다.