给定字符串中的日期名称,如何在当前周内获得表示该日期的Time对象?

时间:2012-05-30 01:26:56

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

给定带有日期名称的字符串,即"Wednesday",如何在当前周(周一至周日)内获得表示该日的时间对象?

例如,如果当前日期是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。

2 个答案:

答案 0 :(得分:7)

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

出于您的目的,您可以使用"this week"参考:

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

..这应该与预期的一样。

答案 1 :(得分: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

与慢性病不同,这种方法会考虑周日到周六运行数周(因为这是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
相关问题