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


107

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

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

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


1
명확하고 명확한 의미를 원하는 것을 이해하지만 어떤 특정 문제가 발생 DateTime합니까?
Jeff Sternal 2011 년

15
1 방법 시작시 시간을 제거하는 것을 기억해야합니다. 2 날짜에만 작동한다는 사실을 잘 전달하지 못합니다. 이것은 예를 들어 좁은 유형으로 충분할 Db에서 저장 및로드 할 때 중요합니다. 프로그래밍은 컴퓨터가 아닌 사람을위한 친교입니다
Carlo V. Dango 2011 년

5
나는 날짜 클래스가 없다는 것이 큰 문제이며 DateTime을 사용하는 것이 전혀 좋지 않다고 말하고 싶었습니다. "날짜"를 날짜-시간으로 저장하자마자 로케일 / 시간대 일광 절약 문제의 인질이됩니다. 시간 부분을 버리면 시계가 바뀌는 날 (!) 모든 날짜를 되돌릴 수 있습니다. 그리고 다른 시간대의 사용자는 날짜-시간을 변환하려고 할 때 다른 날짜를 보게됩니다. 날짜-시간은 정확한 시간을 나타내는 데는 좋지만 (어떤 지점에서든 지피) 추상적 인 날짜를 나타내는 데는 매우 적합하지 않습니다.
TheMathemagician

2
나중에 비슷한 질문 stackoverflow.com/questions/7167710/… , Jon Skeet은 Date가 있어야한다고 말합니다.
goodeye

8
날짜 전용 데이터 유형은 정수 데이터 유형이 10 ​​진수이므로 DateTime입니다. 시간 부분을 버릴 수 있기 때문에 날짜가 필요 없다고 주장하는 사람들은 소수점 부분을 버릴 수 있으므로 정수가 필요하지 않다고 말하는 것과 비슷합니다. 우리 세계에는 시간이없는 날짜라는 개념이 있습니다. 3 월 5 일은 3 월 5 일 00:00:00이 아닙니다.
모호한

답변:


55

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

  • 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 또는 다른 곳으로 변환하지 않도록 매우주의 할 때만 사용해야합니다. 시간대.


2
System.Time.Date.NET 프레임 워크에서 끝날 경우 : /
Robert Jørgensgaard Engdahl

1
오늘 이것을 사용하고 corefx myget 피드를 구독 System.Time하면 다른 패키지와 마찬가지로 가져올 수 있습니다 . 아직 "공식적"이 아닙니다.
Matt Johnson-Pint

16

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

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


61
전용 Date 클래스의 큰 장점은 시간대와 일광 절약 시간의 복잡성으로 인해 어려움을 겪지 않는다는 것입니다.
Dimitri C.

3
@DimitriC. 동의하지 않습니다. UTC와 함께 DateTime을 사용할 수 있으며 설명 된 문제와 함께 DateTime을 사용하면 문제가 발생하지 않습니다. 날짜 만 원하는 경우에도 시간을 포함하는 수학을 수행 할 수 있습니다 (예 : 20 x 2 시간을 빼면 날짜를 알려주세요). 오늘부터).
Robert MacLean

@Robert MacLean : UTC DateTimes 사용의 편리함을 강조해 주셔서 감사합니다. 나는 몇 가지 테스트를했고 DateTimeKind. Unspecified는 빼기와 관련하여 UTC처럼 작동합니다. 따라서 실제로 작업중인 DateTime의 "종류"에 대해주의하면 모든 것이 잘 될 것입니다.
Dimitri C.

10
UTC와 시간대와 관련된 모든 것에 대해 생각하는 것은 별도의 Date 클래스로 쉽게 피할 수 있기 때문에 에너지 낭비 일뿐입니다. 그리고 Date와 DateTime 사이에 어떤 혼동도 보이지 않습니다.
maulik13

6
C #에는 실제로 Date 클래스가 있어야한다는 데 동의합니다. 시간대 변환은 잠수함 버그의 끊임없는 소스 일뿐만 아니라 시간 기반이 아닌 영업일 기반의 작업을 처리 할 때 매우 고통 스럽습니다.
Julian Birch

12

나는 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를 사용하여 기계의 시간을 가져 오기 때문인지 질문했습니다. 그래서 저는 "비즈니스 규칙"이 "너무 결합되어"있기 때문이라고 말하고 싶습니다. 그들은 저에게 그것을 털어 놓았습니다.


이 게시물은 기본 제공 날짜 클래스가없는 디자인 결정 뒤에있는 생각에 대한 통찰력을 제공합니다. 그들에게 보낸 질문은 무엇입니까? 나는 @TheMathemagician이 위에 열거 한 바로 그 이유 때문에이 결정에 동의한다는 것을 의미하지는 않습니다.
Robert Jørgensgaard Engdahl

@ RobertJørgensgaardEngdahl 슬프게도 더 이상 해당 이메일 계정에 액세스 할 수 없습니다. 그러나 나는 왜 그들이 DateTime 구조에서 Time과 Date를 함께 결합했는지 물었다 고 생각합니다. 그리고 제가 TheMathemagician에 동의한다고 생각했습니다. MS는이 디자인 접근 방식을 택했다고 생각합니다. 왜냐하면 국제적인 회사로서 그들의 요구를 충족시키기 때문입니다. 그리고 지금은 그것을 변경하기 늦었습니다.
MVCDS

2
아마도 MS는 돼지 전체를 다루고 SpaceTime클래스를 구현할 수 있습니다 ! 아인슈타인에 따르면 공간과 시간은 밀접하게 연결되어 있으므로 둘 다 구분할 필요가 없습니다. 단순히, 여기서 (!!!!!!!!!!!) 나는 C 번호에 좀 새로운 해요,하지만 난 말을해야, 그것은 VB.NET에서 오는 지뢰밭이다 date, Today(), now, 등 번호가 DateTime없는 쓰레기 접두어, 비웃음. (이 세미콜론이 대소 문자 구분은 확실히 그냥 지금 날 촬영 귀찮은입니다 그리고!!)
SteveCinq

2
그리고 자신의 SQL Server에는 Date유형이 있고 결과 는 유형이어야합니다. 유형 결과가 시간없이 문자열로 예상되는 Date경우 Date. 예를 들어 Delphi는 Date를 DateTime으로 사용하지만 Date 및 DateTime에 대해 다른 유형 정보를 입력합니다.
user2091150 jul.

1
Kirill Osenkov는 "왜 별도의 날짜 및 시간 클래스 DateTime 클래스가 없는가?" 라는 질문에 대답하고 있습니다. 실제 Q는 "왜되지 별도의 날짜 및 시간 클래스가?". 날짜-시간 개념 의 많은 사용 사례에 대해 날짜와 시간이 하나의 클래스로 결합되어야 함을 이해합니다 . 그러나 날짜 개념 의 유효한 사용 사례만큼이나 그 이상은 아니더라도 적어도 많을 것 입니다. 물론 시간 개념 의 유효한 사용 사례도 많이 있습니다.
Tom


4

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

yourdatetime.Date;

화면에 표시하는 경우

yourdatetime.ToShortDateString();

.Date 부분은 내가 찾던 것입니다.
Brendan Vogt 2013 년

3

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


db datetime은 C # datetime과 다릅니다. db datetime에는 시간대가 없으므로 실제로 특정 순간을 참조하지 않습니다. 그러나 C #은 인스턴트가 UTC 시대 이후의 틱임을 알고 저장합니다.
artsrc 2011 년

2
토론은 전용 DATE에 대한 것입니다. datetime 부분에 대한 것이 아니므로 당신이하려는 요점을 이해하지 못합니까?
Pleun

이것은 질문에 대한 답을 제공하지 않습니다. 작성자에게 비판이나 설명을 요청하려면 게시물 아래에 댓글을 남겨주세요.
Barranka 2015 년

@Barranka-질문에 "C #에 날짜 클래스가없는 이유는 무엇입니까?"
STLDev

2

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


1
날짜 만 사용하든 원하지 않든간에 이것이 나쁜 결정이라고 생각하지 않습니다. 나는 당신을 반대 투표하지 않을 것이지만 그것은 내 의견입니다.
JonH 2011 년

잘 말한 것 같지 않습니다. 추상화 / 우아함의 관점에서 2 개 또는 3 개의 유형을 갖는 것이 얼마나 더 적절한 지 알 수는 있지만 실제로는 그 자체로 많은 문제가 없습니다. 내 요점은 .NET 프레임 워크에 머리를 긁적 거리게 할 수있는 많은 것들이 있으며, 특히이 "문제"가 일부 끔찍한 설계 결정 (일반적인 제약).
siride 2011 년

+1이 사실이기 때문입니다. .NET의 유일한 문제 (또는 가장 큰 문제)였습니다. :-) :-) DATE 및 TIME 유형을 추가하는 데 필요한 SQL Server 버전은 몇 개입니까? 그리고 그들은 (적어도 무결성 이유로) 훨씬 더 유용 있었다
xanatos

나는 또한 "모든 것이 -100 점에서 시작"하는 것이 열악한 프레임 워크를 만드는 좋은 방법이라고 생각하며 이것이 쓰레기에 갇힌 것들 중 하나 일 수 있다고 덧붙여 야합니다.
siride 2011 년

2
코드의 한 부분이 .Date 속성을 사용하지 않아 제대로 비교되지 않았기 때문에이 문제에 물 렸습니다. 나는 확실히 이러한 유형의 오류를 방지하기 위해 모든 시간을 저장하지 않는 날짜 유형에 대한 필요가 생각
JoelFan

2

왜? 우리는 추측 만 할 수 있으며 엔지니어링 문제를 해결하는 데 많은 도움이되지 않습니다. 좋은 추측은 DateTime그러한 구조체가 가질 수있는 모든 기능을 포함하고 있다는 것입니다.

정말 중요하다면 DateTime날짜 만 노출하는 (또는 DateTime.Date속성을 살펴 보는) 자신의 변경 불가능한 구조체로 감싸 십시오 .


2

Robert의 대답 외에도 DateTime.ToShortDateString방법이 있습니다. 또한 실제로 Date 객체를 원하면 항상 Adapter 패턴을 사용하고 원하는 항목 (예 : 월, 일, 연도) 만 노출하는 DateTime 객체를 래핑 할 수 있습니다.


2

DateTime.Date의 시간 부분을 차단 하는 속성 이 항상 있습니다 DateTime. 자신의 날짜 유형으로 DateTime을 캡슐화하거나 래핑 할 수 있습니다.

왜 그런지 질문에 대해서는 Anders Heljsberg에게 물어봐야 할 것 같습니다.


1

날짜를 알기 위해서는 시간을 포함하는 시스템 시간 (틱 단위)을 알아야합니다. 그렇다면 왜 그 정보를 버릴까요?

DateTimeDate당신은 시간에 대해 전혀 신경 쓰지 않는 경우 속성을.


1

예, System.DateTime도 봉인되어 있습니다. 이전 게시물에서 언급 한대로 시간의 문자열 값을 가져 오기 위해 사용자 지정 클래스를 생성하여이 게임을하는 사람들을 보았습니다.

class CustomDate
{
    public DateTime Date { get; set; }
    public bool IsTimeOnly { get; private set; }

    public CustomDate(bool isTimeOnly)
    {
        this.IsTimeOnly = isTimeOnly;
    }

    public string GetValue()
    {
        if (IsTimeOnly)
        {
            return Date.ToShortTimeString();
        }

        else
        {
            return Date.ToString();
        }
    }
}

새 클래스없이 일반 이전 DateTime 유형에서 GetShortTimeString을 쉽게 추출 할 수 있으므로 불필요 할 수 있습니다.


0

Date 또는 Today 속성을 사용하여 DateTime 개체에서 날짜 부분 만 가져 오는 경우.

DateTime today = DateTime.Today;
DateTime yesterday = DateTime.Now.AddDays(-1).Date;

그런 다음 시간 구성 요소가 자정으로 설정된 경우에만 날짜 구성 요소를 가져옵니다.


1
이 내가 원하는 것을 확실히 아니다
카를로 V. 경단

@Carlo V. Dango : 동의하지 않습니다. 정확히 당신이 원했던 것 같아요.
siride 2011 년

1
@Carlo V. Dango : 이러한 속성으로 인해 달성 할 수없는 작업을 구체적으로 찾고 있습니까?
eph_tagh 2011 년

5
매우 쉽습니다. Date 메모리 공간은 아마도 DateTime의 메모리 공간의 절반에 불과할 것입니다 (64 비트 대신 32 비트). 당신의 어리석은 동료가 당신의 날짜에 .AddHours (1)를 변경하지 않고 "날짜 만"의 POV에서 "동일하게 유지"하지 않았 음을 확신 할 것입니다. (오류의 경우) DateTime이 DateTimeKind.Local로 설정되고 시간이 UTC로 정규화되면 Date가 아마도 변경 될 것입니다 (XmlSerialization을 사용하고 JSON으로 잘못 왕복) ... 충분합니까?
xanatos 2011 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.