2

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

4

2 回答 2

7

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

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

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

..这应该像预期的那样工作。

于 2012-05-30T01:42:28.037 回答
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
于 2012-05-30T02:14:51.750 回答