你必须想想你实际上说了什么:
Date.strptime('25/01/2017', '%Y/%m/%d')
您是说您想要年份0025、月份01 和日期20(它去除了其余部分)。最后你会得到0025-01-20。
您不能只依靠Date.strptime 为您进行验证。
最好是通过正则表达式实际解析它并进行验证。
为您的格式提供一个可能的正则表达式(一种简单的方法):
'25/01/2017'.match(/\d{4}\/\d{2}\/\d{2}/)
在你的情况下你会得到nil,因为它不匹配。
如果您获得匹配,您将获得:
#<MatchData "2017/01/25">。
问题是这不会检查日期的正确格式。您仍然需要检查 strptime 是否可以解析结果(如 Tom Lord 提供的链接中的)。
另一方面,您也可以仅使用正则表达式进行检查,这可能相当复杂:(以下正则表达式检查 yyyy/mm/dd 格式):
^(?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(\/)(?:0?2\1(?:29)))|(?:(?:[1-9]\d{3})(\/)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[13-9]|1[0-2])\2(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8])))))$
那么你马上就知道日期的格式是否正确,并且你不必用strptime检查解析它。
编辑:
在处理时间时,请记住始终进行自己的检查!不要依赖函数。时间问题是您有很多例外,即使您有 ISO 8601,也许其他一些应用程序可能不遵循它。
根据评论,我想深入了解strptime
现在我想将注释粘贴到源代码中(在 date_s_strptime 函数和 data_core.c 中):
/*
* call-seq:
* Date.strptime([string='-4712-01-01'[, format='%F'[, start=Date::ITALY]]]) -> date
*
* Parses the given representation of date and time with the given
* template, and creates a date object. strptime does not support
* specification of flags and width unlike strftime.
*
* Date.strptime('2001-02-03', '%Y-%m-%d') #=> #<Date: 2001-02-03 ...>
* Date.strptime('03-02-2001', '%d-%m-%Y') #=> #<Date: 2001-02-03 ...>
* Date.strptime('2001-034', '%Y-%j') #=> #<Date: 2001-02-03 ...>
* Date.strptime('2001-W05-6', '%G-W%V-%u') #=> #<Date: 2001-02-03 ...>
* Date.strptime('2001 04 6', '%Y %U %w') #=> #<Date: 2001-02-03 ...>
* Date.strptime('2001 05 6', '%Y %W %u') #=> #<Date: 2001-02-03 ...>
* Date.strptime('sat3feb01', '%a%d%b%y') #=> #<Date: 2001-02-03 ...>
*
* See also strptime(3) and #strftime.
*/
你也可以看到像 sat/feb 这样的字符串,所以解析器可以处理字符串也就不足为奇了。 待续 - 深入研究 C 代码