Date.parse терпит неудачу, если системная дата - 2017-02-01

-4

У меня возникла странная проблема с методом Date.parse.

Я попробовал несколько рубиновых версий, и это случается во всех них. Тесты, приведенные ниже, выполнялись в версии 2.1.10.

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

Если системная дата 2017-01-31, она работает нормально:

2.1.10 :002 > system('date')
Ter 31 Jan 2017 11:24:08 BRST
=> true
2.1.10 :003 > Date.parse("29%2F10%2F2015")
=> #<Date: 2017-01-29 ((2457783j,0s,0n),+0s,2299161j)>

Но если системная дата сегодня, она терпит неудачу:

2.1.10 :002 > system('date')
Qua 1 Fev 2017 11:24:27 BRST
=> true
2.1.10 :003 > Date.parse("29%2F10%2F2015")
ArgumentError: invalid date
from (irb):3:in 'parse'
from (irb):3
from /Users/fernando/.rvm/rubies/ruby-2.1.10/bin/irb:11:in '<main>'

Я, вероятно, обойдусь этим, используя другой метод для синтаксического анализа этой даты, но меня интересует, почему сегодня он провалился.

Является ли 2017-02-01 специальной датой для рубина?

спросил(а) 2021-01-25T12:18:07+03:00 4 месяца, 2 недели назад
1
Решение
89

Date.parse - это метод, который пытается проанализировать дату из данной строки, используя ряд эвристик, чтобы поддерживать множество разных форматов без указания фактического формата. Таким образом, если формат не ясен, всегда возможно, что Ruby приходит к разным выводам, чем вы.

Чтобы понять, как Ruby анализирует вашу строку, вы можете использовать

Date._parse("29%2F10%2F2015")
# => {:mday=>29}

Как вы можете видеть, Ruby может получить день месяца как 29 из переданной строки, но не получает никакой дополнительной информации. Чтобы сформировать действительную дату, Ruby заменяет отсутствующие части с текущей даты. Теперь, с февраля 2017 года только 28 дней, результирующая дата здесь недействительна, но будет действительна в январе.

Тем не менее, результат не то, что вам на самом деле кажется нужным. Вместо этого попробуйте сначала преобразовать дату в более понятную строку и повторите попытку, используя подход Эрика Думинила в другом ответе на этот вопрос:

require 'date'
require 'uri'

string = '29%2F10%2F2015'
Date.strptime(URI.unescape(string), '%d/%m/%Y')
# => #<Date: 2015-10-29 ((2457325j,0s,0n),+0s,2299161j)>

Как вы можете видеть, с Date.strptime вы можете указать точный формат проанализированной строки и, таким образом, быть уверенным, что он либо правильно разбирается, либо выдает ошибки.

ответил(а) 2021-01-25T12:18:07+03:00 4 месяца, 2 недели назад
77

У вас есть три проблемы:

    "% 2F" здесь не должно быть "2017-02-01" может быть "1 февраля" или "2 января". Date.parse полагается на системную дату для синтаксического анализа строки.

Если вы знаете, какой формат у вас есть, вы действительно должны использовать Date.strptime:

require 'date'
require 'uri'

def parse_url_date(url_date)
Date.strptime(URI.unescape(url_date), '%d/%m/%Y')
end

puts parse_url_date("29%2F10%2F2015")
#=> 2015-10-29
puts parse_url_date("01%2F02%2F2017")
#=> 2017-02-01

ответил(а) 2021-01-25T12:18:07+03:00 4 месяца, 2 недели назад
77

%2F - это кодированное значение URL-адреса для перемотки вперед (/)

поэтому вам нужно сначала decode url-encoded string

> require 'open-uri'
#=> true
> string = "29%2F10%2F2015"
#=> "29%2F10%2F2015"
> date = URI::decode(string)
#=> "29/10/2015"
> Date.parse(date)
#=> #<Date: 2015-10-29 ((2457325j,0s,0n),+0s,2299161j)>

Является ли 2017-02-01 специальной датой для рубина?

нет, это не особо;)

> s = "2017-02-01"
> Date.parse(s)
#=> #<Date: 2017-02-01 ((2457786j,0s,0n),+0s,2299161j)>

ответил(а) 2021-01-25T12:18:07+03:00 4 месяца, 2 недели назад
45

Если вы знаете, что ваши "даты" кодируются по URL-адресу, вы должны сначала их декодировать по URL-адресу. Используйте URI.unescape() для этого, затем передайте значение, которое оно возвращает, в Date.parse().

Date.parse(URI.unescape("29%2F10%2F2015"))

ответил(а) 2021-01-25T12:18:07+03:00 4 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема