Вы должны думать, что вы на самом деле сказали:
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
проанализировать результат (как в ссылке, предоставленной Томом Лордом).
С другой стороны, вы можете проверить это также только с помощью регулярного выражения, которое может быть довольно сложным: (следующие проверки регулярных выражений 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