我应该如何模拟任意时间段?

时间:2010-09-15 22:53:43

标签: c# data-modeling

我很难设想一个可以存储以下时间段的对象模型:

"Any Wednesday from 2:00PM to 3:00PM"
"April 1, 2010"
"All April for any year"
"Any day in April from 2:00PM to 3:00PM for any year"
"Any day 1:30PM to 2:00PM"
"Any April 1 to Any April 3"

有时候这段时间是特定日期,有时则是一周中的某一天加上时间跨度。也许整整一个月。

针对模型测试给定的DateTime是一个单独的问题,我将在以后解决。有没有办法在POCO中模拟这个想法?我在画一个空白。

我不是在寻找一组代表两个不同时间点的DateTime。我正在寻找一种结构,用于存储您用于创建手机呼叫计划或轮班轮换的相同类型的时间段。

4 个答案:

答案 0 :(得分:1)

存储两个DateTimes有什么问题?

当你需要用它来呈现/做一些其他形式时,它的表示可以改变成你想要的任何形式,但是在你用它们做的任何操作中都必须有起点和终点。

因此,当您需要字符串表示时,您只需要一些自定义逻辑来判断DateTimes是否在同一天(然后仅输出一天),如果该日期是当前周(仅输出当天)等等。

当然你也可以保持一定的粒度或从代码中获取 - 如果变量没有时间信息那么很明显输出应该只是“4月1日到4月3日”;如果起点和终点恰好落在一个月,那么只输出月份。

我认为这比听起来容易,因为你只需要为日期的每个组件处理几个案例。它还将使以后的比较和匹配间隔更容易。当然,实际的代码可以比我描述的更好的结构 - 我不建议使用几个大的嵌套ifs!

答案 1 :(得分:1)

就个人而言,我可能会使用一堆nullables,例如:

public class /* or struct? */ ArbitraryPointInTime
{
    public int? Year { get; private set; }
    public int? Month { get; private set; }
    public int? Day { get; private set; }
    public int? Hour { get; private set; }
    public int? Minute { get; private set; }
    public int? Second { get; private set; }
    public TimeZone TimeZone { get; private set; }

    // Bunch of constructors that construct a valid structure
    // Prevent nonsensical combinations, e.g. Second specified but Minute null
}

public class /* or struct? */ ArbitraryTimePeriod
{
    public ArbitraryPointInTime? Start { get; private set; }
    public ArbitraryPointInTime? End { get; private set; }

    // Bunch of constructors as above
}

然后我会考虑操作这些数据所需的方法。我个人会保持结构不可变,并让每个方法返回一个新的实例(除非它返回一个bool或其他东西)。为每种方法编写一个规范,并仔细思考所有的角落情况。 Eric Lippert在这个问题的评论中给出了一些例子。记下每种方法在每种情况下应该做什么,即使答案是“抛出异常”。

然后实施规范。

然后写一堆单元测试。 :)

答案 2 :(得分:1)

我参与了一个提出类似问题的系统。我们的决议是Schedule,它定义了一个总体起点和范围。结束时间,每个都有一个(最多七个)ScheduleDay的集合,代表一周中的几天。

Schedule
StartDateTime
EndDateTime

ScheduleDay
DayOfWeek (enum for Mon, Tues etc)
StartTime (time of day, expressed as minutes)
EndTime (time of day, expressed as minutes)

这允许时间段,例如2010年3月1日至2010年9月10日的每周二下午1点至下午3点;例如相当复杂但仍处于模式形成的时间段。

但是,这仍然有点笨拙。您真正想要的是gant图表的数据表示;形成时间间隔的“开”和“关”期间的集合。

如果我正在设计这个系统,我会考虑存储一个带有DateTime的一元函数,并返回一个bool来描述该时间段内是否存在给定时间。您的业​​务对象需要委托;它可能只是if (date.Year == 2010) return true else return false,或者它可能非常复杂,具体取决于您所代表的时间段,但它允许完全可扩展的时间段(不限制可以表示的内容)。

不幸的是我不知道如何在数据库中查询它,它显然不是POCO。

答案 3 :(得分:0)

您可以编写一个存储开始时间(DateTime)的类和一个表示从开始时间开始的时间段的TimeSpan。正如Eric所说,在设置开始日期时你必须考虑时区。