Joda Time LocalTime 24:00结束
我们正在创建一个调度应用程序,我们需要在白天代表某人的可用时间表,无论他们在哪个时区。从Joda Time的Interval中获取一个提示,它表示两个实例之间的绝对时间间隔(开始包含,结束独家),我们创建了一个LocalInterval。 LocalInterval由两个LocalTimes组成(开始包含,最终排他),我们甚至为Hibernate中的持久化做了一个方便的类。
例如,如果有人从下午1:00到下午5:00可用,我们将创建:
new LocalInterval(new LocalTime(13, 0), new LocalTime(17, 0));
到目前为止一直很好 - 直到有人想在某天从晚上11点到午夜才有空。由于间隔结束是独占的,因此应该很容易表示:
new LocalInterval(new LocalTime(23, 0), new LocalTime(24, 0));
确认!不行。这会抛出异常,因为LocalTime不能保持大于23的任何小时。
这对我来说似乎是一个设计缺陷--- Joda没有考虑到有人可能想要一个代表非包容性端点的LocalTime。
这真是令人沮丧,因为它在我们创造的非常优雅的模型中打了一个洞。
我有什么选择 - 除了分支Joda并在24小时内取出支票? (不,我不喜欢使用虚拟值的选项---比如23:59:59 ---代表24:00。)
更新:对于那些一直说不存在24:00的人,这里引用ISO 8601-2004 4.2.3注释2,3:“一个日历日[24:00]的结束与[00]重合:00]在下一个日历日的开始......“和”表示[hh]具有值[24]的表示仅优选表示时间间隔的结束....“
没有找到相关结果
已邀请:
9 个回复
傻零凰死授
默认情况下,构造函数将00:00视为开始日期,但是有一个备用构造函数用于手动创建一整天的间隔:
有一个原因,为什么这个构造函数不只是有一个开始时间和“是一天结束”标志:当与具有下拉列表的时间用户界面一起使用时,我们不知道用户是否会选择00:00(渲染为24:00),但我们知道由于下拉列表是在范围的末尾,因此在我们的用例中它表示24:00。 (虽然LocalTimeInterval允许空间隔,但我们不允许在我们的应用程序中使用它们。) 重叠检查需要特殊的逻辑来处理24:00:
同样,如果isEndOfDay()返回true,则转换为绝对Interval需要在结果中添加另一天。重要的是,应用程序代码永远不会从LocalTimeInterval的开始和结束值手动构造Interval,因为结束时间可能表示结束时间:
当在数据库中持久化LocalTimeInterval时,我们能够使kludge完全透明,因为Hibernate和SQL没有24:00的限制(并且实际上没有LocalTime的概念)。如果isEndOfDay()返回true,则我们的PersistentLocalTimeIntervalAsTime实现存储并检索24:00的真实时间值:
和
令人遗憾的是,我们必须首先编写一个解决方法;这是我能做的最好的事情。
土投
的
? 虽然因为你的开始和结束时间是包容性的,但是23:59:59真的是你想要的。这包括第23个小时的第59分钟的第59秒,并在00:00:00准确结束范围。 没有24:00(使用
时)。
淘圃跺枯替
不处理
因为没有24:00这样的事情。 此外,如果您想表示介于晚上9点到凌晨3点之间的间隔,会发生什么? 这有什么问题:
你只需要处理结束时间可能在开始时间“之前”的可能性,并在必要时添加一天,并且只希望没有人想要表示超过24小时的间隔。 或者,将间隔表示为
和
或
的组合。这消除了“超过24小时”的问题。
丧泉缝锋
在这种情况下,我发现在Joda-Time周围编写一个实现运算符的包装器非常简单,并且减少了思想/数学和API之间的阻抗。即使只是将24:00包含在00:00。 我确实同意24:00的排除在一开始就让我烦恼,如果有人提供解决方案,那将会很好。幸运的是,鉴于我使用时间间隔由环绕语义支配,我总是最终得到一个包装器,顺便解决了24:00的排除问题。
闯舱酮
或
。后者稍微灵活一点。这需要正确支持从23:00到03:00的间隔。
畦桨存灯
,实际上因为夏令时长达11小时。 从15:00-24:00可用,然后您可以编码为
,这将扩展到2011-03-13T15:00 - 2011-03-14T00:00,最终将需要2011-03-13T24:00。这意味着您将在下一个日历日使用00:00的LocalTime,就像已提出的那样。 当然最好直接使用24:00 LocalTime和ISO 8601一致,但这似乎不可能在JodaTime内部改变很多,所以这种方法似乎是较小的邪恶。 最后但并非最不重要的是,你甚至可以延长一天的障碍,比如
......
超可林
怪酞撩匹
这意味着MIDNIGHT常量对问题不是很有用,正如有人建议的那样。
街茬
的任何一端捕获日期,因此您的班级也没有捕获足够的信息来说明夏令时。
通常为3.5小时,但也可能是2.5或4.5小时。 您应该使用开始日期/时间和持续时间,或者开始日期/时间和结束日期/时间(包括开始,独占结束是一个很好的默认选择)。如果您打算显示结束时间,使用持续时间变得棘手,因为夏令时,闰年和闰秒等事情。另一方面,如果您希望显示持续时间,则使用结束日期变得非常棘手。存储两者当然是危险的,因为它违反了DRY原则。如果我正在编写这样的类,我将存储结束日期/时间并封装用于通过对象上的方法获得持续时间的逻辑。这样,类类的客户端并不都会提供自己的代码来计算持续时间。 我编写了一个例子,但是有一个更好的选择。使用Joda时间的标准Interval Class,它已接受一个开始时刻和持续时间或结束时刻。它也会愉快地为您计算持续时间或结束时间。可悲的是,JSR-310没有间隔或类似的类。 (虽然可以使用ThreeTenExtra来弥补这一点) Joda Time和Sun / Oracle(JSR-310)的相对聪明的人都非常仔细地考虑了这些问题。你可能比他们聪明。这是可能的。然而,即使你是一个更明亮的灯泡,你的1小时可能无法完成他们多年来所做的事情。除非你处于一个深奥的边缘情况中,否则花费时间和金钱来花费精力再次猜测它们。 (当然在OP JSR-310时尚未完成......) 希望上述内容能够帮助那些在设计或修复类似问题时找到这个问题的人。