【问题标题】:Business date/holiday handling营业日/节假日处理
【发布时间】:2011-04-18 19:04:21
【问题描述】:

我已经发布了this question for C#,但我可能改用 Ruby。所以我对 Ruby 提出了同样的问题:

我正在寻找一个与 Perl 模块 Date::Manip 类似的 Ruby 类/库/模块,就商务/假日日期而言。在 Perl 中使用该模块,我可以给它传递一个日期,并确定它是工作日(即周一至周五)还是假期。假期很容易在配置文件中定义(参见Date::Manip::Holidays)。您可以输入适用于每一年的“固定”日期,例如:

12/25                           = Christmas

或每年的“动态”日期,例如:

last Monday in May              = Memorial Day

或给定年份的“固定”日期,例如:

5/22/2010                       = Bob's Wedding

您还可以传入一个日期并取回下一个/上一个工作日(即不是周末也不是节假日的任何一天)。

在 Ruby 世界中有人知道类似的事情吗?

【问题讨论】:

    标签: ruby date


    【解决方案1】:

    您可以使用假期宝石。 http://rubygems.org/gems/holidays

    一些国家(和地区)假期已经预定义,您可以定义自己的假期定义。

    【讨论】:

    • 我想将它们存储在数据库中,我认为这个 gem 存储在 yml 文件中。还有其他建议吗?
    【解决方案2】:

    business_timegem 应该可以满足您的需求。

    README 文档底部的示例是一个很好的开始示例:

    require 'rubygems'
    require 'active_support'
    require 'business_time'
    
    # We can adjust the start and end time of our business hours
    BusinessTime::Config.beginning_of_workday = "8:30 am"
    BusinessTime::Config.end_of_workday = "5:30 pm"
    
    # and we can add holidays that don't count as business days
    # July 5 in 2010 is a monday that the U.S. takes off because 
    # our independence day falls on that Sunday.
    three_day_weekend = Date.parse("July 5th, 2010")
    BusinessTime::Config.holidays << three_day_weekend
    friday_afternoon = Time.parse("July 2nd, 2010, 4:50 pm")
    tuesday_morning = 1.business_hour.after(friday_afternoon)
    

    您可能需要chronic gem 来帮助您从配置文件中构建假期日期。但是 YMMV 因为您的示例 5 月的最后一个星期一chronic 中不起作用。 Hackaround 是做这样的事情:

    # last monday in May (2010)
    Chronic.parse('last monday', :now => Time.parse('2010-06-01'))
    

    并查看tickle gem,它在chronic 之上工作,以了解添加重复事件的方法。

    /I3az/

    【讨论】:

      【解决方案3】:

      你可以看看我的Workpattern gem。它允许您指定工作和休息时间。它旨在生成类似于 Microsoft Project 和 Primavera P6 等规划工具中使用的“日历”,因此您可以精确到分钟。

      这是一个简单的例子:

      创建一个新的 Workpattern mywp=Workpattern.new('My Workpattern',2011,10) 这是从 2011 年开始的 10 年,但您可以将其延长或缩短。

      告诉它你希望周末休息,并且你也想在一周内休息,所以你在早上 9 点到 12 点和下午 1 点到 6 点之间工作。

      mywp.resting(:days => :weekend)
      mywp.resting(:days =>:weekday, :from_time=>Workpattern.clock(0,0),:to_time=>Workpattern.clock(8,59))
      mywp.resting(:days =>:weekday, :from_time=>Workpattern.clock(12,0),:to_time=>Workpattern.clock(12,59))
      mywp.resting(:days =>:weekday, :from_time=>Workpattern.clock(18,0),:to_time=>Workpattern.clock(23,59))
      

      现在只需使用分钟计算

      mydate=DateTime.civil(2011,9,1,9,0)
      result_date = mywp.calc(mydate,1920) # => 6/9/11@18:00
      

      1920 是 4 天 * 一天 8 小时 * 60 分钟和小时。

      我编写 gem 来学习 Ruby - 只是触及了表面。

      【讨论】:

        【解决方案4】:

        查看biz gem。

        这是一个示例配置:

        require 'biz'
        
        Biz.configure do |config|
          config.hours = {
            mon: {'09:00' => '17:00'},
            tue: {'00:00' => '24:00'},
            wed: {'09:00' => '17:00'},
            thu: {'09:00' => '12:00', '13:00' => '17:00'},
            sat: {'10:00' => '14:00'}
          }
        
          config.holidays = [Date.new(2014, 1, 1), Date.new(2014, 12, 25)]
        
          config.time_zone = 'America/Los_Angeles'
        end
        

        当您使用可选的核心扩展时,可以通过以下方式轻松确定日期是否为工作日:

        require 'biz/core_ext'
        
        Date.new(2014, 12, 25).business_day? # => false
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-04
          • 1970-01-01
          • 2023-03-26
          • 2020-12-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多