Shp*_*ord 20 ruby ruby-on-rails date
我需要计算两个日期之间的工作日数.我怎样才能使用Ruby(或者Rails ......如果有特定于Rails的帮助程序)来解决这个问题.
同样,我希望能够在指定日期添加工作日.
因此,如果一个日期在星期四下降,我增加了3个工作日,它将在下周二返回.
mik*_*kej 31
看看business_time.它可以用于你要问的两件事.
计算两个日期之间的工作日:
wednesday = Date.parse("October 17, 2018")
monday = Date.parse("October 22, 2018")
wednesday.business_days_until(monday) # => 3
Run Code Online (Sandbox Code Playgroud)
将工作日添加到给定日期:
4.business_days.from_now
8.business_days.after(some_date)
Run Code Online (Sandbox Code Playgroud)
历史答案
当最初询问这个问题时,business_time没有提供business_days_until方法,所以提供了以下方法来回答问题的第一部分.
这对于不需要任何其他功能的人来说仍然有用,business_time并且希望避免添加额外的依赖项.
def business_days_between(date1, date2)
business_days = 0
date = date2
while date > date1
business_days = business_days + 1 unless date.saturday? or date.sunday?
date = date - 1.day
end
business_days
end
Run Code Online (Sandbox Code Playgroud)
这也可以进行微调,以处理Tipx以您希望的方式提及的情况.
sho*_*one 18
我们过去常常使用mikej的答案中建议的算法,并发现计算25,000 个数年的范围每个需要340秒.
这是另一种渐近复杂度为O(1)的算法.它在0.41秒内完成相同的计算.
# Calculates the number of business days in range (start_date, end_date]
#
# @param start_date [Date]
# @param end_date [Date]
#
# @return [Fixnum]
def business_days_between(start_date, end_date)
days_between = (end_date - start_date).to_i
return 0 unless days_between > 0
# Assuming we need to calculate days from 9th to 25th, 10-23 are covered
# by whole weeks, and 24-25 are extra days.
#
# Su Mo Tu We Th Fr Sa # Su Mo Tu We Th Fr Sa
# 1 2 3 4 5 # 1 2 3 4 5
# 6 7 8 9 10 11 12 # 6 7 8 9 ww ww ww
# 13 14 15 16 17 18 19 # ww ww ww ww ww ww ww
# 20 21 22 23 24 25 26 # ww ww ww ww ed ed 26
# 27 28 29 30 31 # 27 28 29 30 31
whole_weeks, extra_days = days_between.divmod(7)
unless extra_days.zero?
# Extra days start from the week day next to start_day,
# and end on end_date's week date. The position of the
# start date in a week can be either before (the left calendar)
# or after (the right one) the end date.
#
# Su Mo Tu We Th Fr Sa # Su Mo Tu We Th Fr Sa
# 1 2 3 4 5 # 1 2 3 4 5
# 6 7 8 9 10 11 12 # 6 7 8 9 10 11 12
# ## ## ## ## 17 18 19 # 13 14 15 16 ## ## ##
# 20 21 22 23 24 25 26 # ## 21 22 23 24 25 26
# 27 28 29 30 31 # 27 28 29 30 31
#
# If some of the extra_days fall on a weekend, they need to be subtracted.
# In the first case only corner days can be days off,
# and in the second case there are indeed two such days.
extra_days -= if start_date.tomorrow.wday <= end_date.wday
[start_date.tomorrow.sunday?, end_date.saturday?].count(true)
else
2
end
end
(whole_weeks * 5) + extra_days
end
Run Code Online (Sandbox Code Playgroud)
business_time具有您想要的所有功能.
从自述文件:
#you还可以计算两个日期之间的业务持续时间
friday = Date.parse("December 24, 2010")
monday = Date.parse("December 27, 2010")
friday.business_days_until(monday) #=> 1
Run Code Online (Sandbox Code Playgroud)
将工作日添加到给定日期:
some_date = Date.parse("August 4th, 1969")
8.business_days.after(some_date) #=> 14 Aug 1969
Run Code Online (Sandbox Code Playgroud)
小智 5
这是我的(非宝石和非假日)工作日计数示例:
first_date = Date.new(2016,1,5)
second_date = Date.new(2016,1,12)
count = 0
(first_date...second_date).each{|d| count+=1 if (1..5).include?(d.wday)}
count
Run Code Online (Sandbox Code Playgroud)