Недельная нумерация ISO-8601 против нумерации "Outlook" в PHP - PullRequest
8 голосов
/ 04 февраля 2010

Недавно я столкнулся с большой проблемой, поскольку у меня есть система, которая платит клиентам еженедельно.

Как мы все знаем, в году 52 недели, и для него есть стандарты. Я использую PHP aka date ('W'), чтобы получить номер недели из даты, которая рассчитывает его в соответствии со стандартом ISO-8601.

Вот несколько ссылок:

Но вот вопрос: в 2009 году 53 недели. Похоже, что по григорианскому календарю в течение 400 лет есть 71 год с 53 неделями. Это одна вещь, которую я не знал, и, вероятно, многие не знали.

Согласно Википедии:

2009-12-31 - это 2009-W53-4 (2009 год ИСО имеет 53 недели, продолжая григорианский 2009 год, который начинается и заканчивается четвергом, в обоих концах - три дня).

и функция даты в PHP полностью ее учитывает.

Если вы загляните в MS Outlook и покажете день недели в календаре, он появится через 52 недели. с 28 декабря 2009 г. по 3 января 2010 г., неделя 1. Это еще один стандарт? Стандарт США или что-то?

Если так, то почему PHP не может это поддерживать? Кто-нибудь делал функцию, которая это поддерживала?

Правильно ли иметь 53 недели? У нас есть клиенты из Европы и США.

Ответы [ 5 ]

5 голосов
/ 04 февраля 2010

Outlook не следует никаким стандартам для нумерации недель. Он имеет две настройки, которые определяют нумерацию недель, называемые «Первый день недели» и «Первая неделя года».

Установив «Первый день недели» на понедельник и «Первую неделю года» на «Первую 4-дневную неделю», можно смоделировать стандарт ISO.

Каждый пользователь должен будет выполнить эту настройку в соответствии со стандартом ISO.

Я не знаю ни одного отдельного стандарта США, и, видимо, не знаю и Outlook.

4 голосов
/ 04 февраля 2010

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

Нумерация недели Outlook несколько эквивалентно следующему:

$dummyWeek = floor((date('z') + (date('N') - 1)) / 7) + 1;

Для выставления счетов лучше использовать ISO8601 в качестве стандарта. Фактически, если вы посмотрите на свои налоги, которые вы собираетесь заполнить в этом году, они описывают последний финансовый год как 53-недельный.

Проблема способа подсчета в Outlook заключается в том, что неделя не гарантируется равной 7 дням. Например, OW01-2010 скомпрометирован всего на 2 дня: пт 1 января, суббота 2 января. Это очень короткий платежный период в течение недели.

ISO8601 недели гарантированно будут длиться 7 дней, поэтому нам нужна високосная неделя каждые 4/5/6 лет.

Какой из этих вариантов вы бы предпочли:

  • ISO8601: Время от времени бывает 53 недели, но каждый из них длится 7 дней.
  • Outlook: наличие случайных 52/53 недель в году, но при этом приходится платить два раза в год за половину недели.
2 голосов
/ 09 ноября 2011

Вот как я это решил. Примечание: я пишу код на PHP, но алгоритм, реализованный на SQL, является важной частью моего кода ниже. Также обратите внимание, что я обработал '2028-12-31' отдельно, потому что это особая дата, в которой 54 обозначает номер недели.

// generate an sql that calculates the outlook week of $date (until 2033)
function sqlWeek ($date) {
     $week = "if( ". $date . " = '2028-12-31', 54, (week( " . $date . ", 0) + if( (year( " . $date . ") - 1) in (2011, 2016, 2022, 2033), 0, 1)) MOD (if (year( ". $date .") = 2028, 54, if( (year( ".$date." ) - 1) in (2011, 2016, 2022, 2033), 53, 52))))";

     return "concat( if( char_length( ".$week." ) < 2, concat( '0', ".$week." ), ".$week." ), '/',  year($date) )";
} 
0 голосов
/ 04 февраля 2010

Просто предупреждение, если вы используете PHP, вы также можете использовать MySQL. MySQL НЕ следует недельным соглашениям ISO-8601, но достаточно близко, чтобы вы могли подумать. Как другие люди отмечают в Outlook, пытаться имитировать нестандартный нестандартный способ вычисления числа недель не стоит!

0 голосов
/ 04 февраля 2010

Вне мира за пределами США больше, чем внутри - и ISO 8601, вероятно, используется более широко за пределами США, чем внутри.

Первоначальное утверждение «год имеет 52 недели» верно только частично, как вы уже нашли. Что касается недель ISO, вы можете закончить с 53 неделей, как отмечено в Википедии. Вы можете иметь до трех дней в году N + 1 на неделе 52 года N или на неделе 53 года N. Вы также можете иметь до трех дней года N-1 на неделе 1 года N. И вам нужно определить как «неделя-год» ISO, так и «неделя» - потому что, когда григорианский календарный год равен N, недельный год ISO может быть годом N-1 или N + 1 (в зависимости от того, какой конец год, с которым вы работаете). Вот почему, например, в strftime () есть отдельные спецификаторы формата («% Y», «% y», «% g», «% G») (но учтите, что стандарт POSIX считает, что дни до первого понедельника января относятся к неделе 0 текущего года, а не к неделе 52 или 53 предыдущего года).

Кажется, нет надежного «американского стандарта» для «недели». Вы получите разные результаты в зависимости от программного обеспечения, которое вы используете. Если вы посмотрите на определение недели Oracle , то первые семь дней года - это неделя 1; в конце года у вас 1 или 2 дня на неделе 53.

См. Также SO 274861 для реализации кода недели ISO. Даже если вы не пишете код на языке, алгоритм должен быть понятен.

...