【问题标题】:Given a day name in a string, how can I get a Time object representing that day within the current week?给定字符串中的日期名称,如何获取表示当前一周内该天的 Time 对象?
【发布时间】:2012-06-04 06:02:22
【问题描述】:

给定一个带有日期名称的字符串,即"Wednesday",我怎样才能得到一个表示当前一周(周一 - 周日)内那一天的 Time 对象?

例如,如果当前日期是 5 月 29 日星期二,并且字符串是 "Monday",则时间对象应该表示 Monday 28 May。如果字符串是"Friday",则应该是Friday 1 June

如果当前日期是 6 月 5 日星期二,并且字符串是 "Monday",则时间对象应该表示 Monday 4 June。如果字符串为"Friday",则应为Friday 8 June

我正在使用 Rails 3.2.0 和 Ruby 1.9.2。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 time


    【解决方案1】:

    对于这些类型的文本日期引用有一个非常方便的 gem,称为 Chronic:
    http://chronic.rubyforge.org/

    为了您的目的,您可以使用"this week" 参考:

    Chronic.parse("monday this week")
    Chronic.parse("friday this week")
    ..etc..
    

    ..这应该可以正常工作。

    【讨论】:

    • 请注意,Chronic 的“本周”概念是从周一到周日。所以今天,5 月 29 日星期二,Chronic.parse('monday this week') 昨天(5 月 28 日)返回,但 Chronic.parse('sunday this week')next 星期日(6 月 3 日)返回。这可能是您的想法,也可能不是。
    • 谢谢..是的 Ben 特别提到了周一到周日的一周类型。所以它会为他正常工作。
    • 哎呀,没看到那个括号。抱歉打扰了。
    【解决方案2】:

    计算起来很简单,但是你必须先解析日期名称,这意味着你需要一个它们的列表:

    WEEKDAY_NAMES = %w<Sunday Monday Tuesday Wednesday Thursday Friday Saturday>
    

    如果您想避免对它们进行硬编码(如果您仍在使用 Ruby 1.8,甚至尊重语言环境设置),您可以这样做:

    WEEKDAY_NAMES = (3..9).map { |i| Time.at( i * 86400 ).utc.strftime '%A' }
    

    然后你可以使用这样的逻辑来获取数字:

    wday = WEEKDAY_NAMES.each_with_index.find{|name,number|name == 'Wednesday'}[1]
    

    或者,更好的是,建立一个名称->数字对的散列:

    wday_from_name =  Hash[*WEEKDAY_NAMES.each_with_index.to_a.flatten]
    wday = wday_from_name['Wednesday']
    

    一旦你有数字形式的目标工作日:

    now = Time.now
    wday_this_week = now + (wday - now.wday) * 86400
    

    与 Chronic 不同,此方法考虑从周日到周六的周数(因为 Time#wday 数字就是这样工作的,其中 0 表示周日)。不过,您可以轻松地调整它以使用不同的日期作为一周的第一天。

    WEEK_START = wday_from_name['Monday']
    wday_this_week = now + 
        ((wday - WEEK_START)%7 - (now.wday - WEEK_START)%7) * 86400
    

    由于您在 Rails 中,您可以使用 ActiveSupport 核心扩展使其更漂亮,例如:

    WEEKDAY_NAMES = (3..9).map { |i| Time.at( i.days ).utc.strftime '%A' }
    
    wday_this_week = now + 
        ((wday - WEEK_START)%7 - (now.wday - WEEK_START)%7).days
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 2014-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多