有没有办法正确解析月中有太多天数的日期? E.g。
'2016-01-32'
= '2016-02-01'
'2015-12-32'
= '2016-01-01'
这是为了支持我的一些基于JS的前端的简单日期操作。
这是Ruby 2.3.0和Rails 4.2.5。我认为这是在早期版本中工作 - 也许解析规则收紧了?
我宁愿依赖标准库,也不是闰年等知识,而不是自己实现。
答案 0 :(得分:2)
require 'date'
y, m, d = '2016-01-32'.split('-').map(&:to_i)
# => [2016, 01, 32]
last_day_of_month = Date.civil(y, m, -1)
# => #<Date: 2016-01-31 ((2457419j,0s,0n),+0s,2299161j)>
date = last_day_of_month + (d - last_day_of_month.day)
# => #<Date: 2016-02-01 ((2457420j,0s,0n),+0s,2299161j)>
答案 1 :(得分:2)
您可以使用Date::_parse
(或Date::_iso8601
)解析日期字符串而无需验证:
require 'date'
h = Date._parse('2016-01-32')
#=> {:mday=>32, :year=>2016, :mon=>1}
使用Simone Carletti's suggestion创建日期实例:
Date.new(h[:year], h[:mon]).next_day(h[:mday] - 1)
#=> #<Date: 2016-02-01 ...>
如果日期和月份都超出范围,您可以使用:
h = Date._parse('2016-14-32')
#=> {:mday=>32, :year=>2016, :mon=>14}
Date.new(h[:year]).next_month(h[:mon] - 1).next_day(h[:mday] - 1)
#=> #<Date: 2017-03-04 ...>
next_day
和next_month
分别相当于+
和<<
,因此最后一行也可以写为:
Date.new(h[:year]) << (h[:mon] - 1) + (h[:mday] - 1)
或:
Date.new(h[:year]) << h[:mon].pred + h[:mday].pred
答案 2 :(得分:0)
尝试解析与您提到的日期相似的日期会引发错误
DateTime.parse('2016-01-32')
ArgumentError: invalid date
一种可能的解决方案是为日期解析创建自定义函数/类。您将解析转发到DateTime对象,如果失败并出现该错误,您可以通过剥离日期编号并将其替换为1来重试。
如果成功,则将剩余天数添加到日期。
date = DateTime.parse('2016-01-1')
=> Fri, 01 Jan 2016 00:00:00 +0000
date + (32-1).days
=> Mon, 01 Feb 2016 00:00:00 +0000
现有的核心或Rails库都不会自动为您执行此操作。因此,您需要一个自定义功能。
您应该能够按照上面的说明和示例轻松编写方法。
答案 3 :(得分:0)
这是一种方法:
require 'date'
date_string = '2016-01-50'
year,month,day = date_string.split('-').map(&:to_i)
date = Date.new(year,month)
(day-1).times{date = date.next}
p date #=> 2016-02-19