2010-09-15 87 views
1

我有一个很难设想能存储时间段类似下面的对象模型:我应该如何建模任意时间段?

"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 s。我正在寻找一种结构,可以存储您用来创建手机通话计划或轮班轮换的相同时间段。

+0

你为什么不简单地存储开始和结束时间?是否因为您需要稍后将其转换回普通文本? – 2010-09-15 23:03:20

+2

这个问题并不完全清楚。您是否在问如何构建一个将这些概念呈现给开发人员的类层次结构,然后他们将使用这些类编写代码?如果是这样,那么就根据两件事来推动设计:(1)开发人员想要操作的不同类型的东西是什么;(2)这些东西之间有什么“是一种”关系。 – 2010-09-15 23:26:26

+1

您似乎正在区分*特定*时间段(2010年4月1日)和非特定时间段(下午1:30至下午2:00,在今天?今天?任何一天?)。但是我注意到,即使你的具体时间段是不确定的:一段时间需要一个*时区*来确定一个特定的时刻。 (其中包括夏时制是否生效。)是4月的5月1日12:01 AM?如果“四月”是在一个不同的时区测量的时间,而不是被测试包含的时间。 – 2010-09-15 23:31:13

回答

1

存储两个日期时间有什么问题?

当你需要提出/做其他事情时,它的表示可以改变为你想要的任何形式,但是在你使用它们进行的任何操作中,开始和结束点是必须的。

所以,当你需要一个字符串表示时,你只需要一些自定义逻辑来决定DateTimes是否在同一天(然后只输出一次),如果一天在当前周(只输出当天)等等等等。

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

我认为这比听起来容易,因为你只需要为日期的每个组件处理几个案例。它也会使后面的比较和匹配间隔更加容易。当然,实际的代码可以比我描述的更好地构造 - 我没有办法建议几个嵌套的大ifs!

+0

当然,这是假定始点和终点始终与某个特定时间点相关联。这个问题并不意味着这一点。我读到这个问题的方式,让我觉得他想表达的想法,比如“周一下午2点。在任何一周“或”任何一年四月十六日“。 – Timwi 2010-09-16 00:45:34

+0

@Timwi没错!在我的脑海里似乎没有这样一个模糊的问题...... – 2010-09-16 12:05:25

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 
} 

然后,我会想你的时候,以操纵这个数据需要哪些方法。就我个人而言,我会保持结构不变,并让每个方法返回一个新的实例(除非它返回一个布尔或其他东西)。为每种方法编写一份规范,并认真思考所有的角落案例。 Eric Lippert在这个问题的评论中给了几个例子。写下每种方法在每种情况下应该做的事情,即使答案是“抛出异常”。

然后执行规范。

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

0

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

+0

这个答案需要为每个不同的跨度创建单独的时间段。我想要代表一组规则的东西适用于一系列日期。 – 2010-09-16 13:46:01

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) 

这样的时间段,如“下午1时 - 下午3时每星期二2010 2010年3月1日至九月10”;例如相当复杂但仍然是形成模式的时间段。

虽然这仍然有点笨重。你想想要的是一个甘特图的数据表示;一系列形成时间间隔的“开”和“关”时段。

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

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

相关问题