我正在开发一款需要开放时间概念的应用 (有点像商店)
如何最好地代表这些? 它们将在以后持久存储在数据库中......
到目前为止,我有以下课程:
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
答案 0 :(得分:4)
坚持使用DateTime
我只是使用DateTime,因为它很好地映射到SQL(SQL也使用DateTime),我发现它比使用TimeSpan更具可读性。您也可以使用相同的对象并为其添加日期以获取今天的开放时间。
为什么不是TimeSpan?
因为它的名字真的和它意味着什么。 TimeSpan代表一段时间而不是某个时间点。虽然它在框架中用于表示确切的时间(在TimeOfDay中),但该属性被定义为in the docs:
TimeSpan,表示自午夜以来经过的一天中的一小部分。
但......并不重要
最后它没什么区别,你可以使用TimeSpan,DateTime或你自己的结构。它们的开销很小,它只是归结为你发现更易读和更容易维护的东西。
答案 1 :(得分: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 :(得分:2)
您可以使用TimeSpan来表示一天中的某个时段。
答案 3 :(得分:2)
我认为你可以在内部将其表示为开始的DateTime(它为您提供DayOfWeek),然后为结束时表示TimeSpan,但将它们显示为三个属性,即DateTimes或TimeSpans
现在打开一个更多的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;
}
}