Почему моя дата выходит за пределы допустимого диапазона для одних дат, но не для других?

Я использую bootstrap-datepicker-rails (v. 1.3.0.2) в своем проекте rails 4.0.9 и наблюдаю странное поведение при разработке и производстве, как объясняется в названии. Я уже рассмотрел этот вопрос, но, похоже, моя проблема не такая и более странная, чем у ОП.

Как и он, я получаю ошибку argument out of range при отправке формы (будь то для действия create или действия update), но только для некоторых дат, а не для других.

Например, эта дата вне диапазона (скопировано из моего журнала разработки — фрагмент из параметров, отправленных в контроллер):

"date_received"=>"08/28/2014"

Тем не менее, эта дата в порядке:

"date_received"=>"08/07/2014"

Я думаю, что тот факт, что некоторые выбранные даты сохраняются правильно, исключает проблему форматирования. Я в тупике, как это могло произойти. Любая дата до 13.08.2014 работает, а любая дата после нее возвращает ошибку вне диапазона.

Вот неприятные подробности:

приложение.js:

//= require jquery
//= require jquery.turbolinks
//= require jquery.tablesorter
//= require jquery_ujs
//= require bootstrap
//= require bootstrap-datepicker/core
//= require jquery-ui
//= require turbolinks

приложение.css:

*= require jquery-ui/theme
*= require bootstrap-datepicker
*= require font-awesome
*= require custom
*= require theme.blue
*= require_self

Jobs.js.coffee:

$(document).ready ->

  $ ->
    $(".tablesorter").tablesorter( {sortList: [[2,0]]} )
    $('.datepicker').datepicker()

    return

работа.рб:

(проверка для рассматриваемого поля):

validates :date_received, presence: true

job_controller.rb:

(строка, на которой возникает ошибка):

if @job.update_attributes(job_params)

определение job_params:

def job_params
  params.require(:job).permit(:number, :name, :display_name, :date_received, :market, 
  :job_type, :pose_selection, :pose_selection_label, :pose_selection_deadline, 
  :pk_id, :pk, :flyout_id, :flyouts, :code, :tax_rate, :shipping_handling, :mail_home, 
  :mail_home_amount, :line, :notes, :entered, :entered_by, :verified, :verified_by, 
  :printed, :printed_by, :assembled_by, :shipped, :active, :discount_amount, :data)
end

Куда мне идти отсюда, чтобы устранить эту проблему?


person digijim    schedule 29.08.2014    source источник
comment
Проблема с форматом даты? Предполагается, что дд/мм/гг? Вы пробовали 20.08.14 и считается ли это диапазоном?   -  person SteveTurczyn    schedule 30.08.2014
comment
Я только что поиграл с вводом даты вручную, а не с помощью средства выбора даты. Если я ввожу дату 20140828, она находится в диапазоне. Так же и 20140807. До сих пор не понимаю, как он ошибается через datepicker.   -  person digijim    schedule 30.08.2014
comment
Становится страннее. Даты, начинающиеся в сентябре 2014 года, выбранные с помощью средства выбора даты, также работают нормально. Так что проваливаются только даты с 13.08.2014 по 31.08.2014. Все другие даты, которые я пробовал, работали. Мне нужно выпить.   -  person digijim    schedule 30.08.2014
comment
Вы пробовали 15 сентября через выбор даты?   -  person SteveTurczyn    schedule 30.08.2014
comment
Я имею в виду 15 сентября 2014 года, просто для ясности...   -  person SteveTurczyn    schedule 30.08.2014
comment
15 сентября не получается. То же самое с 30 июля, 31 июля, но не с 1 июля.   -  person digijim    schedule 30.08.2014
comment
Можете ли вы заставить его работать с датой вместо строки? Подсказка: в году всего 12 месяцев.   -  person Andrew Morton    schedule 30.08.2014
comment
Можешь уточнить, @AndrewMorton? Не уверен, как выполнить то, что вы просите.   -  person digijim    schedule 30.08.2014
comment
Понятно, что он читает строку в формате d/m/y (британский формат). Любое значение месяца (среднее) больше 12 не работает.   -  person SteveTurczyn    schedule 30.08.2014
comment
@digijim Если вы используете Date, то дата будет однозначной, независимо от языка. Например. 01.01.2014 — это 1 января 2014 года в большинстве стран мира, но 1 января 2014 года в некоторых регионах (в частности, в США). Дата (2014, 1, 1) недвусмысленна, поскольку указывается как (год, месяц, день). Я не знаю о внутренностях bootstrap-datepicker-rails, но это действительно должно позволять использовать Date, а не String.   -  person Andrew Morton    schedule 30.08.2014
comment
Спасибо за ответы. Я собираюсь вернуться к этому во вторник и посмотреть, что я могу сделать, чтобы моя форма отправила дату, а не строку. Ваше здоровье!   -  person digijim    schedule 30.08.2014


Ответы (1)


Формат по умолчанию для даты, которую возвращает bootstrap-datepicker-rails, — «мм-дд-гггг». Отправка дат в таком формате либо неправильно сохраняет дату, либо приводит к ошибкам «вне диапазона», потому что Rails неверно интерпретирует день как месяц. h/t @SteveTurczyn за то, что открыл мне глаза на этот факт.

@AndrewMorton предложил заставить bootstrap-datepicker-rails отправлять дату, а не строку, но в этот драгоценный камень не встроен такой механизм, насколько мне известно.

Поэтому мне нужно было изменить формат строки, возвращаемой datepicker. После некоторого консольного тестирования я обнаружил, что формат «дд-мм-гггг» успешно сохраняется (конечно, среди других форматов).

Изменение этой строки (из jobs.js.coffee):

$('.datepicker').datepicker()

... к этому:

$('.datepicker').datepicker( { dateFormat: 'dd-mm-yy' } )

заставляет дату, возвращаемую в форму, быть в формате «дд-мм-гггг».

Единственным недостатком этого исправления является то, что после выбора даты с помощью средства выбора даты дата, отображаемая в форме, не форматируется для аудитории США (например, «23-09-2014» вместо «09-23-2014»). Но во всех других представлениях я могу отображать форматирование США с помощью преобразования strftime. Это жертва, на которую я готов пойти ради простоты. По крайней мере, до тех пор, пока у меня не будет рыбы покрупнее.

ОБНОВЛЕНИЕ: это действительно ужасное «решение».

После слишком долгих поисков чьей-либо пользы я наткнулся на этот пост, который намного лучше работа по использованию средства выбора даты с форматированием даты в США. У него есть свои недостатки (см. мой комментарий к посту), но для моих целей подойдет.

person digijim    schedule 02.09.2014