Обеспечение строки в формате времени или даты? - PullRequest
9 голосов
/ 05 августа 2010

У меня есть метод, который анализирует строку в дате, но я хочу проверить, что я не пытаюсь проанализировать нечисловую строку или строку, которая не соответствует формату даты или времени?

как можно это узнать?

на данный момент у меня есть:

if(string=~ /^\D*$/ )
{
return false
else 
do something_else
}

это нормально для нечисловой строки, такой как "UNKNOWN", но не будет работать для "UNKNOWN1"

есть идеи, что я могу использовать, чтобы убедиться, что анализируются только форматы даты или времени?

Ответы [ 4 ]

13 голосов
/ 05 августа 2010

DateTime.strptime v ParseDate.parsedate

Не рассчитано на каламбур, но приведенная здесь информация устарела (2015), а некоторые методы и модули были удалены из Ruby 2.x Я оставляю это здесь на всякий случай, если кто-то где-то еще использует 1.8 .7

Ладно, возможно, там был небольшой каламбур ;-)


Можно подумать, что вы можете использовать Date.parse или DateTime.parse для проверки на неправильные даты (подробнее об Date.parse здесь )

d = Date.parse(string) rescue nil

if d 
   do_something
else
   return false
end

потому что неправильные значения выдают исключение, которое вы можете поймать. Однако предложенные тестовые строки действительно возвращают Date с Date.parse

Например ..

~\> irb
>> Date.parse '12-UNKN/34/OWN1'
=> #<Date: 4910841/2,0,2299161>
>> 

Date.parse просто не достаточно умен, чтобы выполнять работу: - (

ParseDate.parsedate работает лучше. Вы можете видеть, что он пытается проанализировать дату, но в тестовых примерах не находит действительный год или месяц. Больше информации здесь

>> require 'parsedate'
=> true
>> ParseDate.parsedate '2010-09-09'
=> [2010, 9, 9, nil, nil, nil, nil, nil]
>> ParseDate.parsedate 'dsadasd'
=> [nil, nil, nil, nil, nil, nil, nil, nil]
>> ParseDate.parsedate '12-UNKN/34/OWN1'
=> [nil, nil, 12, nil, nil, nil, nil, nil]
>> ParseDate.parsedate '12-UNKN/34/OWN1'
=> [nil, nil, 12, nil, nil, nil, nil, nil]
1 голос
/ 01 сентября 2014

Независимо от того, какой метод вы используете для анализа даты, вы можете проверить строгое соответствие , переформатировав полученную дату и сравнив ее с исходным вводом.Например:

def strict_parse(input, format)
  Time.strptime(input, format).tap { |output| expect(output.strftime(format)).to eq input }
end

Это строго , однако, например, "1/9/2014" не будет анализироваться с форматом "%d/%m/%Y".Это должно быть "01/09/2014", чтобы быть приемлемым.

0 голосов
/ 05 августа 2010

Я бы посоветовал вам составить список форматов даты и даты и времени, которые вы ожидаете и намереваетесь поддерживать.Вы можете определить их, используя strftime совместимые строки, а затем использовать те же строки при разборе дат, используя DateTime#strptime.Попробуйте проанализировать ваши входные строки с каждым поддерживаемым шаблоном, первый, который не выдает исключение, вернет проанализированную дату.Если каждый выдает исключение, строка не является допустимой датой.

0 голосов
/ 05 августа 2010

Парсеры Ruby настроены оптимистично, если вы можете выбросить кучу мусора и получить результат из строки ввода, Date.parse и DateTime.strptime попытаются это сделать.

Вам нужна пессимистичная и строгая проверка, которая означает, что вместо того, чтобы предполагать принятие после попытки поиска мусора с помощью регулярного выражения, вы должны принять отказ и поиск сокровищ с помощью своего регулярного выражения.

ВашПервая проверка: «Является ли строка числовой» использует регулярное выражение, чтобы попытаться найти строку, состоящую полностью из нечисловых символов, и отклоняет ее, если находит ее.\ D (с заглавной буквой D) ищет нечисловые символы, и входные строки будут соответствовать вашему регулярному выражению только в том случае, если оно полностью состоит из 0 или более нечисловых символов.

Скорее всего, у вас получшеудачи со следующей логикой для чисел:

if(string=~ /^\d*$/ )
 something_else
else 
 return false
end

Это соответствует строке, состоящей полностью из 0 или более числовых символов, делает нечто_else , если это находит, и возвращает ложь в противном случае.

Для случаев, когда вы хотите явно искать время и отклонить все другие значения.Для формата HH: MM: SSAM, который допускает пропуск первых 0 для каждого поля, с 12-часовым временем вы можете использовать следующее:

if (string =~ /^[01]?\d:[0-5]?\d:[0-5]?\d[AP]M$/)
  something_else
else
  return false
end

Аналогично для дат, которые вы хотите явно искать для дат, которые являются действительными,и отклонить все другие значения.Для MM / DD / YYYY, который допускает пропуск первых 0 для всех полей, кроме лет, вы можете использовать:

if (string =~ /^[0-1]\d\/[0-3]?\d\/\d{4}/)
  something_else
else
  return false
end

Функции полезности Ruby стараются быть многословными в том, что они принимают, но для проверки, которая не является полезнойчерта характера.Будьте строги, предположите, что все недействительно, пока не докажет обратное, затем примите это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...