2011-03-15 446 views
74

在我們的C#項目中,我們需要沒有時間來表示日期。我知道DateTime的存在,但是它也包含一天的時間。 我想明確說明某些變量和方法參數是基於日期的。因此,我不能使用DateTime.Date財產僅在C#中使用日期的類型 - 爲什麼沒有日期類型?

什麼是標準的方法解決這個問題?當然,我不是第一個遇到這個?爲什麼C#中沒有Date類?

沒有任何人有使用結構,也許在某些日期時間和extensionmethods也許實施一些運營商如==和<,>一個很好的執行?

+1

雖然我明白想要明確,清晰的語義,'DateTime'創建什麼特定問題? – 2011-03-15 15:55:18

+9

1我需要記住在方法開始時刪除小時。 2它不能很好地溝通,它完全依靠日期工作。這是重要的,例如,從Db存儲和加載窄型的就足夠了。編程是人們不是電腦的共融 – 2011-03-15 22:38:32

+0

以後類似的問題http://stackoverflow.com/questions/7167710/net-date-without-time-is-there-one-or-should-i-not-need-one, Jon Skeet說應該有一個日期。 – goodeye 2012-11-25 02:22:05

回答

20

我懷疑沒有專門的純Date類,因爲您已經有DateTime可以處理它。有Date會導致重複和混淆。

如果您希望標準方法查看DateTime.Date屬性,該屬性只給出DateTime的日期部分,並將時間值設置爲午夜(00:00:00)的12:00:00。

+1

+1:我同意,一個專門的日期類是有點不必要的。 – NotMe 2011-03-15 15:55:09

+49

專用Date類的一大優點是它不受時區和夏令時複雜性的影響。 – 2012-05-24 07:48:18

+3

@DimitriC。我不同意 - 你可以使用DateTime和UTC,並且你不會遇到解釋的問題,再加上一個DateTime,即使你想要日期,你仍然可以做數學,涉及時間(即給我日期,如果我減去20 x 2小時從今天開始)。 – 2012-05-24 11:32:11

1

因爲要想知道日期,你必須知道系統時間(蜱),其中包括時間 - 那麼,爲什麼扔掉這些信息?

DateTime有一個Date財產,如果你不關心的時間。

2

誰知道這是爲什麼。 .NET框架中有很多糟糕的設計決定。不過,我認爲這是相當小的一個。您始終可以忽略時間部分,因此即使某些代碼確定讓DateTime引用的日期不僅僅是日期,也應該只關注日期部分。或者,您可以創建一個只代表日期的新類型,並使用DateTime中的函數來完成繁重的工作(計算)。

+1

我真的不認爲這是一個糟糕的決定,無論你是否只使用日期。我不會失望,但這是我的看法。 – JonH 2011-03-15 15:59:23

+0

我不認爲我說得好。儘管我可以從抽象/優雅的角度看到兩種或三種類型會更合適,但我其實本身並沒有太多問題。我的觀點確實是,.NET框架中有很多東西可能會讓你感到頭疼,不值得讓人過度煩惱,特別是考慮到與某些令人震驚的設計決策相比,這個「問題」相當小(通用約束)。 – siride 2011-03-15 16:01:22

+0

+1因爲它是真的......這是.NET的唯一問題(或最大的問題):-) :-) SQL Server需要多少版本才能添加DATE和TIME類型?在那裏他們更有用(至少出於完整性的原因) – xanatos 2011-03-15 16:02:05

3

爲什麼?我們只能推測,並沒有太大的幫助解決工程問題。一個好的猜測是DateTime包含了這樣一個結構將具有的所有功能。

如果真的對你很重要,只需將DateTime換成你自己的不可變結構,只顯示日期(或查看DateTime.Date屬性)。

2

總是有DateTime.Date財產切斷DateTime的部分時間。也許你可以在你自己的Date類中封裝或包裝DateTime。

而且爲什麼,好了,我想你要問安德斯Heljsberg的問題。

2

除了羅伯特的答案,你也有DateTime.ToShortDateString方法。此外,如果您確實需要Date對象,則始終可以使用Adapter模式幷包裝僅顯示所需內容(即月,日,年)的DateTime對象。

3

允許我猜測:也許是因爲直到SQL Server 2008中存在的SQL沒有日期數據類型所以會很辛苦,所以其存儲在SQL服務器?畢竟這是微軟產品?

+0

db日期時間不同於C#日期時間。數據庫日期時間沒有時區,因此它們實際上並不指向特定的時刻。但C#確實知道該時刻是,並自UTC時代以來存儲了時鐘。 – artsrc 2011-09-28 07:03:20

+2

討論的是關於專用DATE的問題,而不是關於日期時間部分,所以我不明白你想要做的點。 – Pleun 2011-09-28 08:01:27

+0

這不提供問題的答案。要批評或要求作者澄清,請在其帖子下方留言。 – Barranka 2015-01-27 20:24:41

3

如果你需要運行日期比較,然後使用

yourdatetime.Date; 

如果要顯示在屏幕上使用

yourdatetime.ToShortDateString(); 
+2

你錯過了這一點.. – 2012-02-01 08:13:35

+0

.Date部分是我在找的東西。 – 2013-10-02 12:23:51

0

如果使用日期或當前屬性來獲取僅從日期部分DateTime對象。

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

然後,只有將時間組件設置爲午夜時,才能獲取日期組件。

+0

這絕對不是我想要的 – 2011-03-15 16:04:12

+0

@Carlo V. Dango:我不同意。我認爲這正是你想要的。 – siride 2011-03-15 16:06:51

+1

@Carlo V. Dango:你特別希望這些屬性不允許你完成什麼? – 2011-03-15 16:09:08

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沒有新的類

9

我已經通過電子郵件發送[email protected],這就是他們的回答

馬科斯,這不是一個好地方,問這樣的問題。嘗試http://stackoverflow.com 簡短的回答是,你需要一個模型來表示一個時間點,而DateTime這樣做,這是實踐中最有用的場景。人類使用兩個概念(日期和時間)來標記時間點的事實是任意的,並且對分離沒有用處。

只有在需要解耦的地方,不要僅僅爲了盲目做事而做事。以這種方式思考:你有什麼問題可以通過將DateTime分成日期和時間來解決?你會得到什麼問題,你現在沒有?提示:如果你看看.NET框架中的DateTime用法:http://referencesource.microsoft.com/#mscorlib/system/datetime.cs#df6b1eba7461813b#references 你會看到大多數是從一個方法返回的。如果我們沒有像DateTime這樣的單一概念,則必須使用參數或元組來返回一對Date和Time。

HTH, 基里爾Osenkov

在我的電子郵件是不是因爲日期時間使用的TimeZoneInfo拿到機器的時候,我會質疑 - 在現在禮。所以我會說這是因爲它太耦合了,他們向我強調這一點。

+0

這篇文章確實給出了沒有內置日期類的設計決策背後的想法。你發送的問題是什麼?我不是故意暗示我同意這個決定是出於上面列出的@TheMathemagician的原因。 – 2016-05-11 12:07:48

+0

@RobertJørgensgaardEngdahl很遺憾,我再也無法訪問該電子郵件帳戶。但我相信我已經問過他們爲什麼在DateTime結構中將Time和Date結合在一起。我認爲我同意TheMathemagician,我認爲MS採取了這種設計方法,因爲作爲一家國際公司,它支付了他們的需求 - 現在是要遲到改變它 - 而分解概念不是。 – MVCDS 2016-05-11 14:54:04

+1

也許MS可能只是去整個豬,並實施一個'SpaceTime'類!嘿,根據愛因斯坦的說法,時間和空間緊密結合,所以我們不需要區分它們,對吧? (!!!!!!!!!!!) 我有點新的C#,但我不得不說,這是從VB.NET來一個雷區在哪裏,簡單地說,'date','今天() ','now'等等。沒有'DateTime'作爲垃圾的前綴,不會瞎搞。 (!而這些分號,這區分大小寫肯定是令人側目剛剛拍攝我吧!) – SteveCinq 2017-11-16 23:11:22

25

允許我的更新添加到這個經典問題:

  • 喬恩斯基特的Noda Time庫是目前相當成熟,並具有日期只有類型,稱爲LocalDate。 (在這種情況下,本地只意味着本地到某人,對於運行代碼的計算機不一定是本地的。)

  • 一個名爲Date的只有日期的類型是通過corefxlab項目建議添加到.NET Core的。您可以在System.Time包中找到它,以及TimeOfDay類型,以及對現有類型的幾種擴展方法。

我顯著研究過這個問題,所以我也給大家介紹幾種原因爲這些類型的必要性:

  1. 有一個專用日期之間的邏輯不一致,和日期在午夜值。

    • 並不是每一個地方天有在每個時區中的午夜。例如:巴西的春季夏令時轉換將時鐘從11:59:59移到01:00:00。

    • 日期時間總是指某一天內的特定時間,而僅包含日期可能指的是一天的開始,一天的結束或當天的整個範圍。

  2. 附加一個時間的日期可能會導致作爲值從一個環境傳遞到另一個,如果時間區不是很仔細觀看改變日期。這通常發生在JavaScript中(它的Date對象實際上是日期+時間),但是也可以在.NET中輕鬆發生,或者在JavaScript和.NET之間傳遞數據時在序列化中發生。

  3. 序列化DateTime與XML或JSON(和其他人)將總是包括時間,即使它不重要。這非常令人困惑,尤其是考慮到出生日期和週年紀念等時間無關緊要的事情。

  4. 結構上,DateTimeDDDvalue-object,但它違反了在幾個方面Single Responsibly Principle

    • 它被設計成一個日期+時間型,但往往被用作日期只(不考慮時間)或僅限於時間(忽略日期)。 (TimeSpan也經常用於時間的一天,但這是另一個話題。)

    • 連接到.Kind屬性的DateTimeKind值拆分單一類型分爲三,該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 !!! 
      

總之,儘管一個DateTime可以用於一個日期而已,它應該只有這樣做時,當每一個使用它的地方是非常小心忽略時間,同時也非常小心,不要嘗試轉換爲UTC或其他時區。

+1

如果只有'System.Time.Date'將在.NET框架結束:/ – 2016-05-11 12:16:50

+0

您可以使用此今天,剛剛訂閱corefx myget feed,你可以像其他軟件包一樣使用'System.Time'。這只是不「官方」呢。 – 2017-02-02 18:50:18

相關問題