目前正在开发一款应用程序,该应用程序需要向运营商显示过去7天或接下来21天内生日的员工列表。
我们有一个包含出生日期的人员数据库,按日期范围选择它们相当简单。但是,我们必须显示未来/过去生日的天数是从今天开始的。
代码目前看起来像:
today = Date.today
dob = staff.dob
days = Date.new(today.year, dob.month, dob.day) - today
if days < 0
"#{ days.abs } days ago"
else
"in #{ days } days"
end
这几乎适用于所有情况,除了到12月底或1月初。因为我们使用today.year
作为年份比较器,如果未来21天溢出到新的一年,我会得到错误的“几天前”读数。 e.g。
今天的日期是20th December 2015
,工作人员的生日是2nd January
,而不是"in 13 days"
,我得到"352 days ago"
。
我知道我可以将代码包装在另一个if / then / else子句中,以检查当前日期是否在12月10日之后,以满足此边缘情况,但日期范围可能会动态更改,而且,代码开始看起来凌乱而且不优雅 - 不像我想要看看ruby代码。
有没有人对如何处理这个问题有更好的建议?
(注意:这是基于Sinatra的项目,所以我没有所有基于ActiveSupport或Rails的魔法,虽然我不反对使用gem,如果它能得到我需要的结果。)
答案 0 :(得分:2)
require 'date'
class BirthDates
attr_reader :year, :month, :day
def initialize(year, month, day)
@year = year
@month = month
@day = day
end
end
def count_days(dob)
today = Date.today
this_year = today.year
days = [this_year-1, this_year, this_year+1].map { |year|
(Date.new(year, dob.month, dob.day) - today) }.min_by(&:abs)
if days < 0
"#{ -days } days ago"
elsif days > 0
"in #{ days } days"
else
"Happy Birthday!"
end
end
让我们试一试。 (今天是10月29日)
dob = BirthDates.new(1908, 12, 28)
count_days(dob) #=> "in 60 days"
dob = BirthDates.new(1999, 10, 27)
count_days(dob) #=> "2 days ago"
dob = BirthDates.new(2014, 10, 29)
count_days(dob) #=> "Happy Birthday"
如果今天是1月5日:
dob = BirthDates.new(1908, 12, 28)
count_days(dob) #=> "8 days ago"
dob = BirthDates.new(1999, 3, 27)
count_days(dob) #=> "in 82 days"
答案 1 :(得分:1)
获得今年,明年和去年的最小日子
today = Date.today
dob = staff.dob
this_dob = Date.new(today.year, dob.month, dob.day)
next_dob = this_dob.next_year
prev_dob = this_dob.prev_year
days = [this_dob - today, next_dob - today, prev_dob - today].min_by{|i| i.to_i.abs}
if days < 0
"#{ days.abs } days ago"
else
"in #{ days } days"
end