如何計算Rails中的下一個和上一個工作日?如何計算Rails中的下一個工作日?
回答
據我瞭解,這是你在找什麼? (測試過)
require 'date'
def next_business_day(date)
skip_weekends(date, 1)
end
def previous_business_day(date)
skip_weekends(date, -1)
end
def skip_weekends(date, inc)
date += inc
while (date.wday % 7 == 0) or (date.wday % 7 == 6) do
date += inc
end
date
end
您可以測試它,如下所示:
begin
t = Date.new(2009,9,11) #Friday, today
puts "Today: #{Date::DAYNAMES[t.wday]} #{Date::MONTHNAMES[t.mon]} #{t.day}"
nextday = next_business_day(t)
puts "Next B-day: #{Date::MONTHNAMES[nextday.mon]} #{nextday.day}"
previousday = previous_business_day(nextday)
puts "back to previous: #{Date::MONTHNAMES[previousday.mon]} #{previousday.day}"
yesterday = previous_business_day(previousday)
puts "yesterday: #{Date::MONTHNAMES[yesterday.mon]} #{yesterday.day}"
end
如果您的日期是星期日,則上述內容不起作用,如果您嘗試從星期日起7天內遞增,則它會陷入無限循環。 – DavidNorth 2012-06-11 11:31:46
@DavidNorth,它工作正常。週日後的下一個工作日可合理地視爲週一。看起來你只應該傳遞1或-1給skip_weekends,這只是其他兩種方法的幫手。 (雖然它會更好,如果它檢查無效的參數,而不是進入無限循環。) – antinome 2014-12-24 21:56:57
我傳遞了Time對象作爲參數,並想知道如何花費超過1秒才能得到結果。我認爲最好是通過'date + = inc.day'來明確表示' – 2017-01-09 12:50:16
那麼,你可以使用類似於昨天= 1.days.ago得到昨天的日期。使用yesterday.strftime('%w')以星期幾作爲整數(0 =星期日,6 =星期六)。如果昨天是0(星期天),那麼本週的前一天將是3.days.ago ...你明白了。
您可以使用明天= 1.days.since獲取明天的日期。
您可能需要在未來的計算工作日開始fr呃週六或週日。 星期一之後的一個工作日是星期二,星期日的一個工作日也應該是星期二 - 應該忽略開始的週末日。 下實現這一點:
class Date
def business_days_future(inc)
date = skip_weekend
inc.times do
date = date + 1
date = date.skip_weekend
end
date
end
# If date is a saturday or sunday, advance to the following monday
def skip_weekend
if wday == 0
self + 1
elsif wday == 6
self + 2
else
self
end
end
end
這個很好。我會和這一起去的。謝謝。 – juanpastas 2013-05-28 22:16:13
隨着holidays-gem你也可以檢查,如果有一個公共假日。如果你這樣做,你必須定義你需要的區域。 假期寶石也允許使用子區域(例如us-va ...)
德國(德)和美國 - 美國(美國)假期的示例代碼。
require 'holidays'
require 'holidays/us'
require 'holidays/de'
class Date
def next_business_day(region=:any)
skip_weekends_and_holidays(1,region)
end
def previous_business_day(region=:any)
skip_weekends_and_holidays(-1,region)
end
def skip_weekends_and_holidays(inc, region = :any)
date = self + inc
while (date.wday == 6 or date.holiday?(region)) do
date += inc
end
date
end
end
獲取關注:skip_weekends_and_holidays
不會增加營業日。如果你從星期一開始增加5天,你將在星期一結束(除非這個星期一不是假期)。如果在5天內有假期,還有額外的增量。
一些測試代碼:
====us======
Today: Monday December 24
Next B-day: December 26 - Wednesday
Previous B-day: December 23 - Sunday
德國具有兩個自由天(25 + 26.12)::
====de======
Today: Monday December 24
Next B-day: December 27 - Thursday
Previous B-day: December 23 - Sunday
[
Date.new(2012,6,8), #Friday
Date.new(2012,6,10), #Monday
Date.new(2012,6,9), #Sunday
Date.new(2012,12,24), #Christmas eve
Date.new(2012,12,26), #After Christmas
].each{|t|
%w{us de}.each{|region|
puts "====#{region}======"
puts "Today: #{Date::DAYNAMES[t.wday]} #{Date::MONTHNAMES[t.mon]} #{t.day}"
nextday = t.next_business_day(region)
puts "Next B-day: #{Date::MONTHNAMES[nextday.mon]} #{nextday.day} - #{Date::DAYNAMES[nextday.wday]}"
previousday = t.previous_business_day(region)
puts "Previous B-day: #{Date::MONTHNAMES[previousday.mon]} #{previousday.day} - #{Date::DAYNAMES[previousday.wday]}"
}
從結果(平安夜)的提取物
更新:我做了另一個版本來確定multipl商天娥:
require 'holidays'
require 'holidays/us'
#~ require 'holidays/de'
class Date
def next_business_day(region=:any)
next_business_days(1,region)
end
def next_business_days(inc, region=:any)
date = self
inc.times{
date = date.next
while (date.wday == 6 or date.holiday?(region)) do
date = date.next
end
}
date
end
def previous_business_day(region=:any)
previous_business_days(1,region)
end
def previous_business_days(inc, region=:any)
date = self
inc.times{
date = date.prev_day
while (date.wday == 6 or date.holiday?(region)) do
date = date.prev_day
end
}
date
end
end
我的測試代碼:
require 'test/unit'
class BDay_Test < Test::Unit::TestCase
def test_2012_06_08_us()
date = Date.new(2012, 6, 8)
assert_equal(Date.new(2012, 06, 10), date.next_business_day('us'))
assert_equal(Date.new(2012, 06, 7), date.previous_business_day('us'))
assert_equal(Date.new(2012, 06, 17), date.next_business_days(7, 'us'))
assert_equal(Date.new(2012, 05, 31), date.previous_business_day(7, 'us'))
end
def test_2012_06_08_de()
date = Date.new(2012, 6, 8)
assert_equal(Date.new(2012, 06, 10), date.next_business_day('de'))
assert_equal(Date.new(2012, 06, 7), date.previous_business_day('de'))
assert_equal(Date.new(2012, 06, 17), date.next_business_days(7, 'de'))
assert_equal(Date.new(2012, 05, 31), date.previous_business_day(7, 'de'))
end
def test_2012_06_10_us()
date = Date.new(2012, 6, 10)
assert_equal(Date.new(2012, 06, 11), date.next_business_day('us'))
assert_equal(Date.new(2012, 06, 8), date.previous_business_day('us'))
assert_equal(Date.new(2012, 06, 18), date.next_business_days(7, 'us'))
assert_equal(Date.new(2012, 06, 1), date.previous_business_day(7, 'us'))
end
def test_2012_06_10_de()
date = Date.new(2012, 6, 10)
assert_equal(Date.new(2012, 06, 11), date.next_business_day('de'))
assert_equal(Date.new(2012, 06, 8), date.previous_business_day('de'))
assert_equal(Date.new(2012, 06, 18), date.next_business_days(7, 'de'))
assert_equal(Date.new(2012, 06, 1), date.previous_business_day(7, 'de'))
end
def test_2012_06_09_us()
date = Date.new(2012, 6, 9)
assert_equal(Date.new(2012, 06, 10), date.next_business_day('us'))
assert_equal(Date.new(2012, 06, 8), date.previous_business_day('us'))
assert_equal(Date.new(2012, 06, 17), date.next_business_days(7, 'us'))
assert_equal(Date.new(2012, 06, 1), date.previous_business_day(7, 'us'))
end
def test_2012_06_09_de()
date = Date.new(2012, 6, 9)
assert_equal(Date.new(2012, 06, 10), date.next_business_day('de'))
assert_equal(Date.new(2012, 06, 8), date.previous_business_day('de'))
assert_equal(Date.new(2012, 06, 17), date.next_business_days(7, 'de'))
assert_equal(Date.new(2012, 06, 1), date.previous_business_day(7, 'de'))
end
def test_2012_12_24_us()
date = Date.new(2012, 12, 24)
assert_equal(Date.new(2012, 12, 26), date.next_business_day('us'))
assert_equal(Date.new(2012, 12, 23), date.previous_business_day('us'))
assert_equal(Date.new(2013, 01, 3), date.next_business_days(7, 'us'))
assert_equal(Date.new(2012, 12, 16), date.previous_business_day(7, 'us'))
end
def test_2012_12_24_de()
date = Date.new(2012, 12, 24)
assert_equal(Date.new(2012, 12, 27), date.next_business_day('de'))
assert_equal(Date.new(2012, 12, 23), date.previous_business_day('de'))
assert_equal(Date.new(2013, 01, 4), date.next_business_days(7, 'de'))
assert_equal(Date.new(2012, 12, 16), date.previous_business_day(7, 'de'))
end
def test_2012_12_26_us()
date = Date.new(2012, 12, 26)
assert_equal(Date.new(2012, 12, 27), date.next_business_day('us'))
assert_equal(Date.new(2012, 12, 24), date.previous_business_day('us'))
assert_equal(Date.new(2013, 01, 4), date.next_business_days(7, 'us'))
assert_equal(Date.new(2012, 12, 17), date.previous_business_day(7, 'us'))
end
def test_2012_12_26_de()
date = Date.new(2012, 12, 26)
assert_equal(Date.new(2012, 12, 27), date.next_business_day('de'))
assert_equal(Date.new(2012, 12, 24), date.previous_business_day('de'))
assert_equal(Date.new(2013, 01, 4), date.next_business_days(7, 'de'))
assert_equal(Date.new(2012, 12, 17), date.previous_business_day(7, 'de'))
end
end
見test_2012_12_24_us()
和date.next_business_days(7,...
您在2013年結束,在此期間每個假期尊重。
下面是一個使用一個簡單的計算,而不是更快的方法是有用的迭代過去的日子。
class Time
def shift_weekdays(num_weekdays)
base = self
# corner case: self falls on a Sat or Sun then treat like its the next Monday
case self.wday
when 0
base = self + 1.day
when 6
base = self + 2.day
end
day_of_week = base.wday - 1 # Monday is 0
weekends = (day_of_week + num_weekdays)/5
base + (weekends*2).days + num_weekdays.days
end
end
該方法在類Time上,但也可以在Date類上使用。
我意識到這是一個古老的線程,但我只需要爲自己工作這一個,我正在尋找一個很小的代碼,如果一個企業有奇怪的開放日(如「週日/週一休息「)。
def next_business_day(from_day)
workdays = [1,2,3,4,5,6]
test_day = from_day + 1.day
return workdays.include?(test_day.wday) ? test_day : next_business_day(test_day)
end
我想這可以再次縮短到這樣的事情,但我認爲它成爲
def next_business_day(from_day)
test_day = from_day + 1.day
[1,2,3,4,5,6].include?(test_day.wday) ? test_day : next_business_day(test_day)
end
不需要在最後一行返回 – piton4eg 2015-11-06 12:06:26
謝謝@ piton4eg,縮短了短版本多一點。 – 2015-11-16 14:08:18
- 1. 如何計算下一個/上一個ISO工作日號碼?
- 2. 計算幾年的下一個工作日
- 3. 如何計算java中當前日期的下一個生日?
- 4. c#如何計算一個月剩餘的工作日
- 5. 計算工作日
- 6. 計算工作日
- 7. 如何計算下個月的日期?
- 8. 如何計算工作日數?
- 9. 計算Postgres中最近的工作日
- 10. 用Javascript計算幾個工作日
- 11. 計算最後n個工作日
- 12. 如何計算今天的8個工作日?
- 13. 如何計算工作日中兩個日期之間的差異
- 14. 如何計算在asp.net中兩個不同日期之間的工作日
- 15. 計算下一個到期日期
- 16. PHP計算下一個事件日期
- 17. 計算Google電子表格中下一個生日的日期
- 18. 我如何確定一天是Rails的一個工作日?
- 19. 日期跳過一年計算下一個生日日期
- 20. 在Excel中計算工作日
- 21. 在JavaScript中計算工作日週期
- 22. 關於計算工作日/節假日
- 23. 用日期參數計算工作日
- 24. 下個月的第一個工作日
- 25. SQL計算Datediff爲8個工作日的一半
- 26. 計算另一個工作簿中工作表的單元格
- 27. 計算一個月的工作時間
- 28. 如何使這個計算器工作?
- 29. 如何計算兩個日期之間有多少個工作日?
- 30. 如何計算下一個當前行?
被認爲是一個工作日的假期不太明顯?工作日只是M-F? – 2009-09-10 17:31:13
僅限M-F(節假日視爲營業日)。 但如果你可以給我過濾假期,這將是非常棒的。 – 2009-09-10 17:36:00
你試過嗎?您應該在您的問題中添加您的代碼嘗試。 – rogeriopvl 2009-09-10 17:39:47