2010-08-25 21 views
4

我開發需要的開放時間 (有點像店)表示時間在C#

如何最好地表示這些概念的應用程序(而非日期和時間)? 他們將在DB以後可以堅持...

到目前爲止,我有下面的類:

public class OpeningTime 
{ 
    public DayOfWeek DayOfWeek { get; set; } 
    public DateTime OpeningTime { get; set; } 
    public DateTime ClosingTime { get; set; } 
} 

所以我虛構的「店」類將是這樣的:

public class Shop 
{ 
    public string Name { get; set; } 
    public string Address { get; set; } 
    public List<OpeningTime> OpeningTimes { get; set; } 
} 

DateTime對於表示類似內容仍然正確:

星期一--9.00 - 17:30

+4

我建議您將類「OpeningTime」重命名爲「OperationHours」 – 2010-08-25 15:33:48

+1

。您在.Net中比在SQL中具有更大的靈活性。想想你想如何將它堅持到表格中,然後在.Net中模擬它(假設你僅僅迎合一個RDBMS,並且這種方式會持續一段時間)。這次你想要多精確? – 2010-08-25 15:39:50

回答

3

就我個人而言,我會使用TimeSpan而不是DateTime,但我聽說其他人表達了相反的觀點。

[Serializable()] 
public class OpeningTime 
{ 
    protected OpeningTime() 
    { 
    } 

    public OpeningTime(DayOfWeek dayOfWeek, TimeSpan fromTime, TimeSpan toTime) 
     : this(dayOfWeek, fromTime.Hours, fromTime.Minutes, toTime.Hours, toTime.Minutes) { } 

    public OpeningTime(DayOfWeek dayOfWeek, int fromHours, int fromMinutes, int toHours, int toMinutes) 
    { 
     if (fromHours < 0 || fromHours > 23) 
     { 
      throw new ArgumentOutOfRangeException("fromHours", "fromHours must be in the range 0 to 23 inclusive"); 
     } 

     if (toHours < 0 || toHours > 23) 
     { 
      throw new ArgumentOutOfRangeException("toHours", "toHours must be in the range 0 to 23 inclusive"); 
     } 

     if (fromMinutes < 0 || fromMinutes > 59) 
     { 
      throw new ArgumentOutOfRangeException("fromMinutes", "fromMinutes must be in the range 0 to 59 inclusive"); 
     } 

     if (toMinutes < 0 || toMinutes > 59) 
     { 
      throw new ArgumentOutOfRangeException("toMinutes", "toMinutes must be in the range 0 to 59 inclusive"); 
     } 

     this.FromTime = new TimeSpan(fromHours, fromMinutes, 0); 
     this.ToTime = new TimeSpan(toHours, toMinutes, 0); 

     if (this.FromTime >= this.ToTime) 
     { 
      throw new ArgumentException("From Time must be before To Time"); 
     } 

     this.DayOfWeek = dayOfWeek; 
    } 

    public virtual DayOfWeek DayOfWeek { get; private set; } 

    public virtual TimeSpan FromTime { get; private set; } 

    public virtual TimeSpan ToTime { get; private set; } 
} 
2

您可以使用TimeSpan來表示一天中的某個時間。

2

我想你可以在內部表示以此爲開始的日期時間(它給你的星期幾),然後結束時間跨度,但它們公開爲三個屬性,或者是DateTime是否或時間跨度

我們開關在一個更DDD的帽子上......你「可以」使用TimeSpan對象來表示一天中的某個時間,但如果我正在考慮DDD條款,我想要考慮商店打開的時間。 TimeSpans可以代表更多的信息,並且每次與他們打交道時都必須特別驗證他們不超過一天的時間。

所以一種方法是創建一個簡單的類來表示您想表示的內容(您可以只包裝一個TimeSpan對象而不是使用幾個整數)。

public struct Time 
{ 
    private readonly int _hour; 
    private readonly int _minute; 
    private readonly int _second; 

    public Time(int hour, int minute, int second) 
    { 
     if (hour < 0 || hour >= 24) 
      throw new ArgumentOutOfRangeException("hour", "Hours must be between 0 and 23 inclusive"); 
     if (minute < 0 || minute > 59) 
      throw new ArgumentOutOfRangeException("minute", "Minutes must be between 0 and 23 inclusive"); 
     if (second < 0 || second > 59) 
      throw new ArgumentOutOfRangeException("second", "Seconds must be between 0 and 23 inclusive"); 
     _hour = hour; 
     _minute = minute; 
     _second = second; 
    } 

    public Time(Time time) 
     : this(time.Hour, time.Minute, time.Second) 
    { 

    } 

    public int Hour { get { return _hour; } } 
    public int Minute { get { return _minute; } } 
    public int Second { get { return _second; } } 

    public override string ToString() 
    { 
     return ToString(true); 
    } 

    public string ToString(bool showSeconds) 
    { 
     if (showSeconds) 
      return string.Format("{0:00}:{1:00}:{2:00}", Hour, Minute, Second); 
     return string.Format("{0:00}:{1:00}:{2:00}", Hour, Minute); 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (obj.GetType() != typeof (Time)) return false; 
     return Equals((Time) obj); 
    } 

    public bool Equals(Time other) 
    { 
     return other._hour == _hour && other._minute == _minute && other._second == _second; 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      int result = _hour; 
      result = (result*397)^_minute; 
      result = (result*397)^_second; 
      return result; 
     } 
    } 

} 

public class OpeningHours 
{ 
    public DayOfWeek DayOfWeek { get; set; } 
    public Time OpeningTime { get; set; } 
    public Time ClosingTime { get; set; } 
    public OpeningHours(DayOfWeek dayOfWeek, Time openingTime, Time closingTime) 
    { 
     DayOfWeek = dayOfWeek; 
     OpeningTime = openingTime; 
     ClosingTime = closingTime; 
    } 
} 
+1

重新發明日期,甜美! – 2010-08-25 16:31:55

+0

您是否應該在您的域中公開嵌入類型? DateTime和TimeSpan都不代表一個通用的時間,他們可以用來這樣做,但這並不能使其正確。你可以將所有東西都存儲爲一個字符串,爲什麼不這樣做呢?它沒有概念意義 – 2010-08-25 23:00:25

3

棒與日期時間

我只想用日期時間,因爲它很好地映射到SQL(SQL使用日期時間也可以),我覺得它比使用時間跨度更易讀。您也可以使用相同的對象並添加日期以獲取「今日」的開放時間。

爲什麼不是TimeSpan?

因爲它的名字是真的,這意味着什麼。 TimeSpan代表了一段時間,而不是一個時間點。雖然在框架用來表示一個確切的時間(在的TimeOfDay),但屬性被定義爲in the docs

表示自午夜經過的一天的餾分A時間跨度。

但...其實並沒有多大關係

最後它沒什麼區別,你可以使用TimeSpan,DateTime或你自己的結構。這兩者都沒有多大的開銷,它只是歸結爲你發現更易讀,更容易維護。