2008-12-16 101 views
28

我在C#中使用DateTime來顯示時間。構建時間時,每個人都使用哪個日期部分?C#日期時間:什麼「日期」使用時,我只使用「時間」?

例如以下是無效的:

//4:37:58 PM 
DateTime time = new DateTime(0, 0, 0, 16, 47, 58); 

因爲沒有零個月或零天。

我是否使用COM的零日期?

//4:37:58 PM 
DateTime time = new DateTime(1899, 12, 30, 16, 47, 58); 

或者SQL Server的?

//4:37:58 PM 
DateTime time = new DateTime(1900, 1, 1, 16, 47, 58); 

我意識到這是任意的,因爲我會忽略代碼中的日期部分,但它仍然是很好的能夠使用:

DateTime duration = time2 - time1; 

回答

我想我喜歡MinValue

DateTime time = DateTime.MinValue.Date.Add(new TimeSpan(16, 47, 58)); 

注意:我不能使用TimeSpan,因爲這不會存儲一天的時間。我知道的原因是因爲沒有辦法顯示它的內容。

這是說TimeSpan記錄了時間跨度,不是時間天的。例如

TimeSpan t = new TimeSpan(16, 47, 58); 

t.ToString(); 

返回的時間跨度在格式小時分鐘,例如:

16:47:58 

而非時間:

4:47:58 PM (United States) 
04:47:58 nm (South Africa) 
4:47:58.MD (Albania) 
16:47:58  (Algeria) 
04:47:58 م (Bahrain) 
PM 4:47:58 (Singapore) 
下午 04:47:58 (Taiwan) 
04:47:58 PM (Belize) 
4:47:58 p.m. (New Zealand) 
4:47:58 μμ (Greece) 
16.47.58  (Italy) 
오후 4:47:58 (Korea) 
04:47:58 ب.ظ (Iran) 
ਸ਼ਾਮ 04:47:58 (India) 
04:47:58 p.m. (Argentina) 
etc 

在其它話說,時間跨度和時間是有區別的。同時也意識到TimeSpan沒有提供將時間跨度轉換爲一天中某個時間的機制 - 這是有原因的。

+7

您說TimeSpan不存儲一天的時間,但DateTime結構有一個名爲TimeOfDay的屬性,類型是TimeSpan。 – 2010-04-29 15:25:23

+0

請考慮編輯出問題的答案。 – 2016-10-25 16:37:50

回答

23

那麼DateTime.MinValue呢?

+0

我喜歡那最好的,而不是硬編碼的數字,但增加了MinValue日期的時間跨度。 – 2008-12-16 21:38:32

2

DateTime.Now.TimeOfDay怎麼樣,並使用TimeSpan

「因爲那不存儲一天的時間。」 - 好吧,如果你認爲自午夜以來的時間爲TimeSpan,那就行了。

「持續時間」,例如,尖叫TimeSpan

+0

減去兩個DateTime會生成一個TimeSpan。 – 2008-12-16 21:19:27

4

鑑於DateTime.TimeOfDay返回TimeSpan,我會使用它。

爲什麼你不能使用TimeSpan?我不明白你的意見,它不存儲一天的時間。

6

TimeSpan當然可以存儲一天中的時間 - 您只需將該值作爲自午夜以來流逝的時間量來對待,這與我們讀取時鐘的方式基本相同。

+0

TimeSpan不存儲一天的時間。更新了問題,向您說明原因。 – 2008-12-16 21:18:28

1

我建議DateTime.MinValue

3

要顯示與當地的文化格式化的時間跨度,只需將其添加到像DateTime.Today日期。類似這樣的:

(DateTime.Today + timeSpan).ToString();

由於您的值確實不代表日期,因此最好將其存儲爲TimeSpan,直到顯示它爲止。

1

您可以使用字符串文字創建新的DateTime。

字符串字面時間:當創建

DateTime t = new DateTime("01/05/2008T01:00:30"); 

在大多數情況下,:

DateTime t = new DateTime("01:00:30"); 

字符串字面日期:

DateTime t = new DateTime("01/05/2008"); // english format 
DateTime t = new DateTime("05.01.2008"); // german format 

對於日期和時間值的日期時間一個日期時間,我將它設置爲DateTime.Now,如果它沒有實際設置爲其他任何東西。如果您手動實例化DateTime,則應該小心DateTimeKind設置正確,否則可能會導致意外。

5

個人而言,我想創建一個自定義Timestruct包含DateTime實例,並且具有相似的屬性,構造等,但不暴露天/月/等等。只需讓所有的公共訪問者都能通過所包含的實例。然後,您可以簡單地將該時代作爲private static readonly DateTime字段,並且您選擇的值無關緊要,因爲它全部包含在自定義結構中。在你的代碼的其餘部分可以簡單地寫:

var time = new Time(16, 47, 58); 
0

使用TimeSpan,如果你有TimeZone問題使它成爲UTC。

1

我可以建議在某些情況下自定義結構可以嗎?它可以有一個Int32支持值(一天有86千萬毫秒;這適合於一個Int32)。

有可能獲得專用屬性:

小時 分 秒 毫秒

你也可以重載運算符,如+, - 等。實現IEquatable,IComparable和其他可能的情況。重載等於,==。重載並覆蓋ToString。

您還可以提供更多的方法來構建從DateTime或附加到日期時間等。

8

讓我們幫忙誰想要一個時間結構的傢伙:

/// <summary> 
/// Time structure 
/// </summary> 
public struct Time : IComparable 
{ 
    private int minuteOfDay; 
    public static Time Midnight = "0:00"; 
    private static int MIN_OF_DAY = 60 * 24; 

    public Time(int minuteOfDay) 
    { 
     if (minuteOfDay >= (60 * 24) || minuteOfDay < 0) 
      throw new ArgumentException("Must be in the range 0-1439", "minuteOfDay"); 
     this.minuteOfDay = minuteOfDay; 
    } 

    public Time(int hour, int minutes) 
    { 
     if (hour < 0 || hour > 23) 
      throw new ArgumentException("Must be in the range 0-23", "hour"); 
     if (minutes < 0 || minutes > 59) 
      throw new ArgumentException("Must be in the range 0-59", "minutes"); 

     minuteOfDay = (hour * 60) + minutes; 
    } 

    #region Operators 
    public static implicit operator Time(string s) 
    { 
     var parts = s.Split(':'); 
     if (parts.Length != 2) 
      throw new ArgumentException("Time must be specified on the form tt:mm"); 
     return new Time(int.Parse(parts[0]), int.Parse(parts[1])); 
    } 


    public static bool operator >(Time t1, Time t2) 
    { 
     return t1.MinuteOfDay > t2.MinuteOfDay; 
    } 
    public static bool operator <(Time t1, Time t2) 
    { 
     return t1.MinuteOfDay < t2.MinuteOfDay; 
    } 
    public static bool operator >=(Time t1, Time t2) 
    { 
     return t1.MinuteOfDay >= t2.MinuteOfDay; 
    } 
    public static bool operator <=(Time t1, Time t2) 
    { 
     return t1.MinuteOfDay <= t2.MinuteOfDay; 
    } 
    public static bool operator ==(Time t1, Time t2) 
    { 
     return t1.GetHashCode() == t2.GetHashCode(); 
    } 
    public static bool operator !=(Time t1, Time t2) 
    { 
     return t1.GetHashCode() != t2.GetHashCode(); 
    } 

    /// Time 
    /// Minutes that remain to 
    /// Time conferred minutes 
    public static Time operator +(Time t, int min) 
    { 
     if (t.minuteOfDay + min < (24 * 60)) 
     { 
      t.minuteOfDay += min; 
      return t; 
     } 
     else 
     { 
      t.minuteOfDay = (t.minuteOfDay + min) % MIN_OF_DAY; 
      return t; 
     } 
    } 

    public static Time operator -(Time t, int min) 
    { 
     if (t.minuteOfDay - min > -1) 
     { 
      t.minuteOfDay -= min; 
      return t; 
     } 
     else 
     { 
      t.minuteOfDay = MIN_OF_DAY + (t.minuteOfDay - min); 
      return t; 
     } 
    } 

    public static TimeSpan operator -(Time t1, Time t2) 
    { 
     return TimeSpan.FromMinutes(Time.Span(t2, t1)); 
    } 
    #endregion 


    public int Hour 
    { 
     get 
     { 
      return (int)(minuteOfDay/60); 
     } 
    } 
    public int Minutes 
    { 
     get 
     { 
      return minuteOfDay % 60; 
     } 
    } 


    public int MinuteOfDay 
    { 
     get { return minuteOfDay; } 
    } 

    public Time AddHours(int hours) 
    { 
     return this + (hours * 60); 
    } 

    public int CompareTo(Time other) 
    { 
     return this.minuteOfDay.CompareTo(other.minuteOfDay); 
    } 

    #region Overrides 
    public override int GetHashCode() 
    { 
     return minuteOfDay.GetHashCode(); 
    } 

    public override string ToString() 
    { 
     return string.Format("{0}:{1:00}", Hour, Minutes); 
    } 
    #endregion 

    /// 
    /// Safe enumerering - whatever interval applied max days 
    /// 
    /// Start time 
    /// Spring in minutes 
    /// 
    public static IEnumerable Range(Time start, int step) 
    { 
     return Range(start, start, step); 
    } 

    /// 
    /// Safe enumeration - whatever interval applied max days 
    /// 
    public static IEnumerable Range(Time start, Time stop, int step) 
    { 
     int offset = start.MinuteOfDay; 
     for (var i = 0; i < Time.Span(start, stop); i += step) 
     { 
      yield return Time.Midnight + (i + offset); 
     } 
    } 

    /// 
    /// Calculates the number of minutes between t1 and t2 
    /// 
    public static int Span(Time t1, Time t2) 
    { 
     if (t1 < t2) // same day 
      return t2.MinuteOfDay - t1.MinuteOfDay; 
     else // over midnight 
      return MIN_OF_DAY - t1.MinuteOfDay + t2.MinuteOfDay; 
    } 
} 
0

沒有太大的差別比較公認的答案。只是爲了實現這個想法。

public class TimeOfDay 
{ 
    public DateTime time; 
    public TimeOfDay(int Hour, int Minute, int Second) 
    { 
     time = DateTime.MinValue.Date.Add(new TimeSpan(Hour, Minute, Second)); 
    } 
}