Moment: неправильный `weekOfYear` для определенных комбинаций dow / doy

Созданный на 21 дек. 2014  ·  13Комментарии  ·  Источник: moment/moment

Похоже, что алгоритм расчета недели недостаточно универсален, так как он неправильно обрабатывает определенные комбинации dow / doy:

// see http://en.wikipedia.org/wiki/Seven-day_week#cite_ref-15
moment.locale(moment.locale(), { week: { dow: 6, doy: 1 } });
moment("2012-12-28", "YYYY-MM-DD").week(); // 51 -- should be 52?
moment("2012-12-29", "YYYY-MM-DD").week(); // 52 -- should be 1
moment("2013-01-01", "YYYY-MM-DD").week(); // 52 -- should be 1
moment("2013-01-08", "YYYY-MM-DD").week(); // 53 -- should be 2
moment("2013-01-11", "YYYY-MM-DD").week(); // 53 -- should be 2
moment("2013-01-12", "YYYY-MM-DD").week(); // 1 -- should be 3
moment().weeksInYear(2012); // 52

Я предполагаю, что что-то не так в функции weekOfYear , если я что-то не делаю не так?

Самый полезный комментарий

Я не могу объяснить причину того, как определяется doy , но вы можете установить его в 7 + dow - janX где janX - это x-е января, которое должно принадлежать неделе. № 1.

Итак, если 1 января должно относиться к неделе № 1, а суббота - это первый день недели, тогда doy = 7 + 6 - 1 = 12 . Для ISO это будет doy = 7 + 1 - 4 = 4 для США это будет doy = 7 + 0 - 1 = 6 .

Все 13 Комментарий

Есть предположения? Это влияет на многие регионы, где первый день недели не воскресенье или понедельник. Если ошибка подтверждена, следует ли мне отправить запрос на перенос для более weekOfYear расчета

Должен признать, что настройка doy меня сильно сбивает. { dow: 6, doy: 12 } означает, что неделя начинается в субботу, а первая неделя - это неделя с 1 января. Если я правильно понимаю, {dow:6, doy: 1} будет означать, что первая неделя всегда будет включать 26 декабря.

Я добавил тест с { dow: 6, doy: 12 } в запрос на перенос.

Вы имеете в виду { dow: 6, doy: 1 } ? Я думаю, что значение doy больше 7 не имеет реального значения .. Это опечатка?

Нет, я имел в виду {dow: 6, doy: 12} . Обратите внимание, что doy _не_ январский день первой недели. {dow: 6, doy: 12} - это стандарт в арабских странах - неделя начинается в субботу, а первая неделя - это неделя, которая включает 1 января.

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

Ого, если это так, то все это время неправильно понимали doy ..

Действительно, согласно документации, localeData.firstDayOfYear() может возвращать любое целое число от 0 до 15 включительно, но мне это кажется таким странным.

Чтобы помочь мне понять, можете ли вы объяснить, почему это 12, а не 1? И что в этом случае будет означать doy из 1 или 4 ? Как именно здесь работает математика? Похоже, вы хорошо это понимаете ...

Я нашел хорошее объяснение , которое делает более очевидным, что такое doy , хотя я до сих пор не могу понять, как оно может быть больше 6 ..

@icambron , не могли бы вы

@usmonster Прошло много времени с тех пор, как я смотрел на это, но с doy values> 6, так что ... .

Я не могу объяснить причину того, как определяется doy , но вы можете установить его в 7 + dow - janX где janX - это x-е января, которое должно принадлежать неделе. № 1.

Итак, если 1 января должно относиться к неделе № 1, а суббота - это первый день недели, тогда doy = 7 + 6 - 1 = 12 . Для ISO это будет doy = 7 + 1 - 4 = 4 для США это будет doy = 7 + 0 - 1 = 6 .

Ах, если это _реализовано_ таким образом, я думаю, это проблема с реализацией. Никакое другое определение, которое я видел (например, ISO, Unicode TR35), не дает подобного определения недели года. Комментарии в API даже не намекают на то, что происходит, хотя теперь я замечаю, что были написаны тесты, которые предполагают именно эту логику, например, я вижу такие строки:

dow : 1, // Monday is the first day of the week.
doy : 7  // The week that contains Jan 1st is the first week of the year.

И в другом файле:

dow : 6, // Saturday is the first day of the week.
doy : 12  // The week that contains Jan 1st is the first week of the year.

Так что ваша оценка реализации выглядит точной. Тем не менее, это просто неприятно, как если бы тесты были написаны для соответствия неработающей реализации.

Это особенно расстраивает, поскольку проще было бы просто исправить реализацию так, чтобы она делала то, что интуитивно понятно (возьмите « janX », которое должно быть в первую неделю), но исправить это сейчас не получится. не иметь обратной совместимости. Тьфу.

Альтернативой может быть отказ от doy и введение новой опции в недельную конфигурацию, например, minDays или dom , чтобы указать минимальное количество «январских дней» (1- 7) это должно быть в первую неделю года. Это переопределит doy если оно было указано случайно.

Есть предположения?

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

Если мы изменим семантику, чтобы она была более значимой для пользователей, это могло бы быть лучше. Но он должен быть обратно совместимым (чтобы новые методы открывали новые числа).

Что касается вашего примера, вы можете заставить его работать, если вы добавите 7 несколько раз к doy, потому что это относительно dow.

Закрытие этого в пользу # 2336

Привет @ichernev. :) Возвращаясь к этому через год, я по-прежнему за реализацию более осмысленной семантики, хотя я почти уверен, что невозможно сделать что-то обратно совместимое без изменения синтаксиса.

вы можете заставить его работать, если вы добавите 7 несколько раз к doy, потому что это относительно dow.

Я не уверен, что это всегда так ... Например, { dow: 0, doy: 6 } не будет означать одно и то же до и после предлагаемого семантического изменения. (Вот почему я предложил отказаться от doy в пользу другого имени.)

Где мне искать дополнительные отзывы по этому поводу? Эта конкретная проблема закрыта, но я могу перенести беседу на moment / momentjs.com # 279 или открыть новую проблему, если это более уместно.

Я также хотел бы отметить это, так как я потратил дополнительный день, пытаясь понять, как работает doy и для этого мне пришлось загрузить источник момента. Было бы здорово ввести новую, более семантически релевантную переменную настройки, как предлагает @usmonster .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги