这里有两个日期,第一个日期大于或等于(gteq),第二个日期小于或等于(lteq)。两个日期都设定了一个规则,即必须落在 3 个月的范围内。一如往常,要确定 gteq 与 lteq 之间的范围,总是有很多方法。我们将针对这个情况讨论三(3)个解决方案,其中第三个方案是最值得考虑的。
解决方案 #1
这个解决方案假设每个月有 30 天。
作为一名 Ruby 新手开发者,你会感到慌张。然后,你赶紧用 Google 搜索怎么做,结果就出来了。

正如 stack overflow 论坛所建议的,你需要对两个日期进行减法运算。然而,这并不适合你的情况,因为你需要以月而不是天来表示差值。用 gteq 减去 lteq(lteq – gteq)来找出差异,会得出一个天数,而这个天数可能并不完全准确,因为涉及到每个月的天数。
大于或等于(gteq)
小于或等于(lteq)
日期操作中常用的术语
想象一下,你正在比较 2019 年 1 月 1 日与 2019 年 4 月 1 日,同时假设 30 天等于 1 个月。那么,你运气不错。但是,如果你处在闰年(例如:2020 年),二月会多出 1 天呢?在 2020 年比较同样的日期,会得出 91 天,而不是 2019 年的 90 天。


考虑到所有这些顾虑,解决方案 #1 可能不是确定两个日期是否在可接受范围内的最佳方法。让我们看看解决方案 #2。
解决方案 #2
这个解决方案假设每个月有 30.42 天,其中每年有 365 天,且没有闰年。
如果日期范围是从二月一日(2 月 1 日)到三月二日(3 月 2 日),那么假设每个月有 30 天并不准确。根据闰年周期的不同,在使用 30 天假设时,两个月可能会被视为一个月。因此,你决定不再把事情复杂化,改为导入 ruby gem,其逻辑封装在类方法中。

在浏览了 Google 搜索结果列出的几个网站后,你来到了一个 gem 仓库。到了这一步,你也许会被某些论点说服,明白为什么 Ruby 本身缺少时间差辅助方法。所以,这个 gem 就来救场了。
看来你终于完成了比较它是否在可接受范围内的任务。在上面的例子中,它确实假设你想检查 gteq 与 lteq 之间的范围是否大于三(3),如果小于或等于则返回 true,如果大于 3 则返回 false。
到了这一步,你感到很满意,让魔法在类内部发生。与此同时,你正以 reuse(重用)之名,继续着自己的无知。不知怎的,你开始好奇究竟发生了什么魔法,于是你发现了真相。它使用的正是解决方案 #2 中的假设,即一个月平均有 30.42 天。
依赖一年中每个月平均有 30.42 天的假设,在每四年就会出错一次,因为那时一个月平均有 30.5 天。解决方案 #2 并非永远胜出,因为这个假设不够准确,尽管它可能适合某些使用场景。让我们来看看最终也是最佳的解决方案 #3。
解决方案 #3
不要使用任何假设。把 gteq 的月份值增加三(3),然后将结果与 lteq 比较,看 lteq 是否大于该结果。
这将会是最简单、也最准确的假设。而且,这个假设应该已经存在于每位 Web 开发者的心中。增加月份值并进行比较,是简单的常识。然而,有时候当有很多事情要考虑时,我们可能就会直接选择愚蠢的解决方案 #1 和 #2。
结论
我其实一直在寻找实现以下目标的方法:
- 如果给定的 gteq 和 lteq 不大于今天。
- lteq 必须始终大于 gteq,或至多相等。
- 范围必须在 2 年期限内,且范围在 3 个月以内。2 年期限内的任何 3 个月范围都是可接受的。
- 如果用户违反了规则,就将日期替换为昨天。
在 Ruby on Rails controller 中,设置一个 before action 钩子,以便在服务用户请求的特定方法开始执行之前运行该逻辑。
如果你也是需要完成这项任务的人,你会怎么处理呢?

发表回复
要发表评论,您必须先登录。