Как получить календарную неделю, чувствительную к году? дата («W») возвращает 52 на 1 января

Как говорится в заголовке, функция даты PHP («W») возвращает календарную неделю (для текущего дня). К сожалению, он возвращает 52 или 53 в течение первых дней большинства лет. Это, по простой мысли, правильное, но очень раздражающее, поскольку 1 января 2012 года не календарная неделя 52, это НЕ календарная неделя текущего года. Большинство календарей определяют это как неделю 0 или неделю 52 предыдущего года.

Это очень сложно, когда вы группируете каждый день в году по календарной неделе: 1 января 2012 года и 31 декабря 2012 года выставляются в одну и ту же группу календарных недель.

Поэтому мой вопрос: есть ли (родная) чувствительная к году альтернатива дате PHP («W»)?

EDIT: Я думаю, что я написал первую версию этого вопроса очень неясным образом, так что это мое редактирование: я ищу функцию, которая возвращает правильную неделю календаря в течение первых дней года. Дата PHP («W») возвращает 52 на 1 января 2012 года, что является «неправильным». Он должен быть 0 или null. Согласно официальным источникам, первая календарная неделя года начинается в первый понедельник года. Итак, если первый день года – это не понедельник, это не неделя 1! Это неделя 0. В статье в Википедии говорится:

Если 1 января находится в понедельник, вторник, среду или четверг, он находится на неделе 01. Если 1 января находится в пятницу, субботу или воскресенье, это происходит на 52 или 53 неделе предыдущего года.

Это становится сложно, поскольку последние дни года также находятся на неделе 52/53. дата («W») не делит на текущий год и предыдущий год.

Это решение конвертирует избыток декабря в неделю 53 и все в январе до 1-й недели до 0-й.

$w=(int)date('W'); $m=(int)date('n'); $w=$w==1?($m==12?53:1):($w>=51?($m==1?0:$w):$w); echo "week $w in ".date('Y'); 

2013-12-31 ==> неделя 53 в 2013 году

2014-01-01 ==> неделя 1 в 2014 году

2015-12-31 ==> неделя 52 в 2015 году

2016-01-01 ==> неделя 0 в 2016 году

И небольшой тестовый прогон, чтобы вы могли убедиться сами 😉

 $id=array(25,26,27,28,29,30,31,1,2,3,4,5,6,7,8); for($iy=2013;$iy<2067;++$iy){foreach($id as $k=>$v){if($k<7){$im=12;}else{$im=1;} if($k==7){++$iy;echo '====<br>';}$tme=strtotime("$im/$v/$iy"); echo date('dm-Y',$tme),' * * '; //THE ACTUAL CODE ================= $w=(int)date('W',$tme); $m=(int)date('n',$tme); $w=$w==1?($m==12?53:1):($w>=51?($m==1?0:$w):$w); //THE ACTUAL CODE ================= echo '<b>WEEK: ',$w,' --- ','YEAR: ',date('Y',$tme),'</b><br>';}--$iy; echo '----------------------------------<br>';} 

Есть ли (родная) чувствительная к году альтернатива дате PHP («W»)?

Нет, нет.

Согласно официальным источникам, первая календарная неделя года начинается в первый понедельник года.

Я не знаю, какие официальные источники вы имеете в виду.

date("W") PHP date("W") возвращает номер недели в соответствии с ISO 8601. Как международный стандарт, ISO 8601 считается одним из, возможно, многих «официальных источников». Если его определение номеров недель не соответствует вашему приложению, вы можете использовать все, что вам нравится.

Если вы используете нестандартное определение «первая неделя года» или используете официальный источник, который не получил широкого признания, ожидайте, что вам придется написать свою собственную функцию для замены date("W") . (Я уверен, что вам нужно написать функцию.)

Дата 2012-01-01 была в воскресенье. ISO 8601, Wikipedia и php согласны с тем, что номер недели ISO для 2012-01-01 составляет 52.

ISO 8601 не определяет неделю 0.

Итак, если первый день года – это не понедельник, это не неделя 1!

Ни ИСО, ни Википедия не говорят об этом. ISO 8601 определяет неделю номер 1 как неделю, в которой первый четверг в этом году. В 2012 году первый четверг был 5 января, так что номер 1 был с 2 января по 8 января. 2012-01-01 был на последней неделе предыдущего года с точки зрения ISO-недель.

Если вы хотите что-то другое, вы можете играть с арифметикой, делением и т. Д. (Например, попробуйте делить дату («z») на 7.) Или вы можете сохранить эти данные в базе данных и провести недели так, как вам нравится.

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

Текст данных в таблице намного проще проверять, чем текст функции php, независимо от того, насколько проста эта функция. И данные наверняка будут одинаковыми для любой программы, которая обращается к ней, независимо от того, на каком языке она написана. (Итак, если ваша база данных когда-нибудь будет иметь программы, написанные на 5 разных языках, доступ к ней, вам не нужно писать, и поддерживать 5 различных функций, чтобы получить номер недели.)

 $d = new DateTime('first monday january '.date('Y')); echo $d->format("W"); 

Есть ли (родная) чувствительная к году альтернатива дате PHP («W»)?

Да, есть.

После долгих исследований и обсуждений с разработчиками я нашел это отличное решение и могу ответить на свой вопрос: Пока date('W'); вернет 01 с первого января 2013 года, strftime('%W'); вернет 00 в тот же день. Это происходит потому, что strftime использует локальную настройку времени [смотрите здесь для получения дополнительной информации].

 // both functions need a timestamp [amount of seconds since 1.1.1970], // not a "date" [like 2013-01-01], so we generate a timestamp. By the way, // mktime uses ... Month, Day, Year (NOT Day, Month, Year) $timestamp = mktime(0,0,0,1,1,2013); // gives back: 01 echo "Week with date(): "; echo date("W", $timestamp); // gives back: 00 echo "Week with strftime(): "; echo strftime('%W', $timestamp);