代码之家  ›  专栏  ›  技术社区  ›  DDulla

vb.net从可用时间列表中计算预约时间?

  •  0
  • DDulla  · 技术社区  · 4 年前

    我试图找到一种有效的方法来计算用户(对象)的预订时间,给定同一用户\对象的免费/可用时间列表。

    我有一个对象,它将返回给定特定日期的“可用”时间。持续时间/结束时间固定为10分钟。

    起始数据示例:

    12/23/2020 8:00 AM
    12/23/2020 9:00 AM
    12/23/2020 1:00 PM
    

    在这种情况下,我需要生成“不可用”时间,并将其插入到具有相当简单模式的数据库中:

    start_date | end_date | start_time | end_time
    

    插入相当简单,我很难确定计算不可用时间跨度的最佳方法。

    使用上面的例子,我需要生成以下时间跨度:

    12/23/2020 12:00 AM - 7:59 AM
    12/23/2020 08:11 AM - 8:59 AM
    12/23/2020 09:11 AM - 12:59 PM
    12/23/2020 1:11 PM - 11:59 PM
    

    有什么框架或库可以帮我完成这项繁重的工作吗?是否有可能在不遍历结果并计算所有偏移的情况下解决这个问题?

    如果有人问“为什么”,将两个遗留系统连接在一起,一个系统会返回给定日期的可用约会,这需要连接到一个需要给定日期的不可用约会的系统中。

    0 回复  |  直到 4 年前
        1
  •  0
  •   Albert D. Kallal    4 年前

    嗯,首先我写了更多的旅游预订系统,然后我就可以动摇了。

    罗塞塔石碑是真的吗?

    您不希望生成或拥有系统PERIOD中未使用的预订时段!!!

    因此,您只需在系统中输入有效的预订(开始时间和结束时间)。startTime应该是一个日期时间列,这将大大降低查询的复杂性。既然你有日期和单独的时间?好吧,那么你的问题会更复杂——我把它留给你。

    鉴于上述情况?在所有情况下发现预订冲突的简单逻辑是:

    发生碰撞时:

    请求开始日期<=结束日期 和 请求结束日期>=起始日期

    现在在上面,我假设日期值或日期时间值。

    那么,如果我想要一份今天的预订清单呢?

    请求DDTStart=2020-12-23上午9点 请求结束时间=2020-12-23下午5点

    因此,任何碰撞都可以通过以下方式发现:

    strWhere=dtRequestStartDate<=预订结束日期_ “和dtRequestEndDate>=预订开始日期”

    现在,假设.net,那么上面的参数应该是这样的

    strWhere=@dtRequestStart<=预订结束日期_ “和@dtRequestEnd>=预订开始日期”

    因此,以上将返回今天上午9点至下午5点的所有预订

    一个引人注目的简单查询!当然,上述查询可以/将会包括检查室、酒店房间或其他任何附加条件。但在所有情况下,上述简单查询都会返回上午9点至下午5点的任何冲突。

    这个系统的美妙之处是什么?只要您不允许在预订系统中进行超圈,那么您就可以在数据库中一次性预订10分钟、20分钟或30分钟的会话。因此,我不需要创建3个10分钟的插槽。

    因此,这意味着您永远不必创建预订时段。整个系统将并且可以通过简单的开始+结束预订记录成为司机。如前所述,您可以预订1小时或40分钟。您的输入(UI)可以简单地将时间跨度限制为10分钟的增量,但这是UI部分。

    现在我想在屏幕上以10分钟为增量显示内容?那么,您必须每小时提交6个请求才能“显示”时间段。对于一整天,建议从上午9点到下午5点,你必须运行8 x 6=48个请求才能得到一个10分钟增量的列表。但话又说回来,你可以只显示一天的现有预订,并允许添加新的预订,但如果有重叠,则不允许。

    因此,如前所述,这里的概念是,您并不真正需要数据库中的“插槽”。我想你可以试试老虎机,但这会让代码变得一团糟。如果你只存储开始和结束?然后我可以说,只需更改日期,就可以将预订推迟到另一天。或者我可以将预订时间从10分钟延长到20或40分钟,只需更改结束时间。只要与上述简单的“测试”没有重叠,我就可以简单地将预订时间更改为40分钟,并且需要零代码来更新多个插槽。将预订时间从40分钟缩短到10分钟也是如此。同样,只需要减少结束时间——对数据库进行一行更新。

    因此,如果可能的话,我会放弃在数据库中拥有“插槽”的概念。如果预订时间只有10分钟,我可能会考虑这样的设计。但是,如果允许10、20或30个,那么您不需要在数据库中存储任何未使用的插槽,而只需要存储一个有效的预订插槽。因此,通过上述查询也可以找到空的未使用时间。(如果查询返回记录,则无法预订)。

    因此,在某些UI中显示空闲时间变得更具挑战性,但显示10或20分钟或任何时间的预订要容易得多,如前所述,您甚至可以通过房间ID的一行更新将整个预订更改为不同的房间。如果没有发生冲突,则允许此预订,并且只需更新一个代表开始+结束时间的简单预订记录即可实现此结果。

    这意味着您也永远不会将预订总额存储在数据库中——您可以查询它们!

    我还发现,如果我说在数据库中存储任何预订总数?好吧,对于复杂的代码,我们总是发现总数往往不完美。因此,我们最终会编写一个例程来浏览数据,总结总数并将其写出来。

    但是,如果你从来没有存储过任何预订的总数(比如公共汽车上的人,或者给定酒店里的人),那么虽然查询这样的显示有点困难,但通过简单的空从tourID中删除一个人就变得非常简单了。

    因此,此显示在Action中显示了上述概念。酒店的可用房间、巴士上预订的人,甚至“团体旅游”的总数都是数据库中未存储的值:

    enter image description here

    那么,在上面,人们预订了公共汽车、预订了房间、使用了房间?所有这些值都不会存储在数据库中。而且也没有插槽。因此,如果我们有一辆公交车,那么我们将容量设置为46,但我们不会创建46个预订位。那么,是公共汽车、酒店还是体检室?您不会提前创建预订时段,只需插入具有开始+结束的预订,然后根据该概念进行查询。

    所以,要在公共汽车上(或者说在考场)找到总数,我会查询当天的总数。如果我想将4人的团体预订从一辆巴士转移到另一辆巴士上呢?然后,对它们所在的给定总线进行一次FK更新,允许整个系统“级联”系统中的现有值。将一个人从1号检查室转移到5号检查室也是如此。您只需更新检查室的FK值。如果没有发生冲突,那么这也是一次单行更新。如果你有多个检查室和多个插槽,那么数据库中一个简单的单行更新就变成了现在必须用大量代码更新多个预订插槽的大杂烩。

    因此,您将资源的“使用”预订为“一天”、“一辆公交车”或“一个房间”,但预订的行为消耗了时间段,而不是为每个“范围”预先创建记录或时间段。因此,这允许您利用相关数据库模型,并减少大量代码,因为您不是针对“插槽”进行编码,而是只针对上午10点到下午4点开放的考场。因此,当天的可用考场只是您在系统中创建的一条记录,然后您现在可以自由预订当天给定的考场范围。当天预订一个房间的时间可以是10分钟,也可以是40分钟,但只有一条记录被添加到数据库中才能实现这一目标(预订)。

    不管上述情况如何,这个简单的碰撞查询适用于任何碰撞(包括整个重叠、现有跨度内,甚至结束或开始与任何预订重叠)。这个查询非常简单,适用于所有碰撞。所以我没有一个库可以共享,但这个简单的预订碰撞查找器查询可以基于这种简单的查询驱动整个系统。