给定带有日期名称的字符串,即"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。
答案 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