2014-11-21 3 views
6

Рубин правильно разбирает первое, но второе неверно. Протестировано с рубинами 1.9.3 и 2.1.2.Ruby неправильно анализирует 2-значный год

Любая идея, как заставить ее работать последовательно? (Мы получаем в датах рождения, как 2 цифры года)

Date.strptime("10/11/89","%d/%m/%y") 
=> Fri, 10 Nov 1989 

Date.strptime("15/10/63","%d/%m/%y") 
=> Mon, 15 Oct 2063 

ответ

3

strptime метод анализирует текст «63» до 2063 года, а не 1963, как вы хотите.
Это потому, что метод решает столетие, используя POSIX standard.

У драгоценного камня chronic есть аналогичная проблема, поскольку он решает столетие, хотя и по-разному.

Решение состоит в том, чтобы установить дату:

d = Date.strptime("15/10/63","%d/%m/%y") 
if d > Date.today 
    d = Date.new(d.year - 100, d.month, d.mday) 
end 

В комментариях этого поста, Стефан предлагает хороший один лайнер:

d = d.prev_year(100) if d > Date.today 

Если вам нужна скорость, вы можете попробовать оптимизировать как это:

d <= Date.today || d = d << 1200 
+0

или 'd = d.prev_year (100), если d> Date.today' – Stefan

+0

Ваш второй пример не учитывает будущие даты в текущем году. – Stefan

+0

@Stefan хорошие моменты, спасибо. Я удалю второй пример - это не так просто и не так быстро. – joelparkerhenderson

-1

Добавить Хронический камень в ваш Gemfile

gem 'chronic'

Тогда просто разобрать его:

Chronic.parse("15/10/68") 
=> 1968-10-15 12:00:00 -0700 
+1

Это только сдвигает проблему: 'Chronic.parse ("15/10/63")' возвращает 2063 – Stefan

+1

@stefan спасибо, что указали, что вне –

3

При использовании %y в strptime, код предполагает, что значения при 68 рассматриваются в 21-м веке, а descirbed here:

год в течение века (0-99). Когда столетие не указано иначе (со значением для% C), значения в диапазоне 69-99 относятся к годам в двадцатом веке (1969-1999 годы); значения в диапазоне 00-68 относятся к годам в двадцать первом веке (2000-2068 гг.).

В chronic камень, кстати, отсечка год 64:

Chronic.parse('15/10/64') 
# => 1964-10-15 12:00:00 +0200 

Chronic.parse('15/10/63') 
# => 2063-10-15 12:00:00 +0300 
+0

Интересно, что Chronic использует другое отображение. Ruby соответствует стандарту POSIX. – Stefan

+0

@Stefan - Они изменили его так, чтобы они могли смутить bsy :-P –

+2

Chronic использует 50-летнее смещение по умолчанию и 2014 - 50 = 1964 – Stefan

Смежные вопросы