Я недавно столкнулся с большой проблемой, поскольку у меня есть система, которую это платит клиентам еженедельно.
Как все мы знаем, год имеет 52 недели, и существуют стандарты для него. Я использую PHP иначе дата ('W') для получения недельного числа от даты, которая вычисляет это согласно стандартному ISO 8601.
Вот некоторые ссылки:
Но вот ПРОБЛЕМА: 2009 год имеет 53 недели. Кажется, что через Григорианский календарь в течение 400 лет существует 71 год, которые имеют 53 недели. Это - одна вещь, которую я не знал, и вероятно многие не сделали также.
Согласно Википедии:
31.12.2009 2009-W53-4 (2009 год ISO имеет 53 недели, расширяя Грегорианский 2009 год, который запускается и заканчивается четвергом в обоих концах с тремя днями).
и функция даты в PHP полностью уважает его.
Если Вы изучите MS Outlook и покажете день недели в календарном представлении, то это появится 52 недели, считая 28 DEC 2009 до 03 января 2010 неделя 1. Этот другой стандарт? Американский стандарт или что-то?
Если так, затем почему PHP не может поддерживать его? Кто-либо делал функцию, которая поддерживала это?
Это корректно, чтобы иметь 53 недели? У нас есть и европейские и американские клиенты.
Я не думаю, что у вас будет проблема здесь. Факт заключается в том, что вы соблюдаете международный стандарт форматирования и подсчета даты и времени ( 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 дней. Перспективы
: 52/53 недели в году в случайном порядке, но необходимо платить два раза в год за «половину недели». Ролан Буман написал приятную статью, объясняющую подводные камни и обходные пути вложенных курсоров здесь: Текст ссылки
-121--4998227-Добавление к другим ответам:
За пределами США мира больше, чем внутри - и ISO 8601, вероятно, используется более широко за пределами США, чем внутри.
Первоначальное утверждение «год имеет 52 недели» является верным лишь частично, как вы обнаружили сейчас. С точки зрения ISO недель можно закончить с 53-й неделей, как отмечается в Википедии. Вы можете иметь до трех дней года N + 1 на неделе 52 года N или до 53 недели года N. Вы также можете иметь до трех дней года N-1 на неделе 1 года N. И вам нужно определить как ISO 'неделя-год', так и 'неделя' - потому что, когда григорианский календарный год равен N, год недели ISO может быть годом N-1 или N + 1 (в зависимости от того, с каким концом года вы работаете). Вот почему существуют отдельные спецификаторы формата («% Y», «% y», «% g», «% G»), например, в strftime () (но обратите внимание, что стандарт POSIX считает, что дни до первого понедельника января приходятся на 0-ю неделю текущего года, а не на 52-ю или 53-ю неделю предыдущего года).
Похоже, нет никакого надежного «стандарта США» для «недели». Вы получаете различные результаты в зависимости от используемого программного обеспечения. Если посмотреть на определение недели Oracle , то первые семь дней года будут 1 недели; у вас есть 1 или 2 дня на неделе 53 в конце года.
См. также SO 274861 для реализации кода номера недели ISO. Даже если вы не кодируете язык, алгоритм должен быть понятен.
Я не C++ парень. Но, в C #, я бы написал его как
enum Enum
{
Enum_One,
Enum_Two
};
Special make_special( Enum e )
{
if(Enums.IsDefined(typeof(Enum),(int)e))
{
switch( e )
{
case Enum_One:
return Special( /*stuff one*/ );
case Enum_Two:
return Special( /*stuff two*/ );
}
}
// your own exception can come here.
throw new ArgumentOutOfRangeException("Emum Value out of range");
}
-121--1855975- Это то, о чем нужно беспокоиться. Компилятор обнаружил, что код в базовом классе может выполняться. Это не будет чисто виртуальный метод, он знает, как их фильтровать. Может, конструктор или деструктор? Режим отказа заключается в том, что формат памяти объекта класса может отличаться в коде клиента от DLL. Причиной этого является очень трудно диагностировать.
Вы будете в порядке, если только вы можете гарантировать, что клиент и DLL скомпилированы с точно такими же параметрами настройки компиляции и ссылки, используя точно такие же версии CRT и этих инструментов. Базовый класс можно сделать гарантированным абстрактным с помощью нестандартного ключевого слова интерфейса __ вместо класса.
-121--5044561-Outlook не соответствует каким-либо стандартам нумерации недель. Он имеет две настройки, определяющие нумерацию недель, называемые «Первый день недели» и «Первая неделя года».
Установив для параметра «Первый день недели» значение «Понедельник», а для параметра «Первая неделя года» значение «Первая 4-дневная неделя», можно смоделировать стандарт ISO.
Каждый пользователь должен выполнить эту корректировку в соответствии со стандартом ISO.
Я не знаю отдельного стандарта США, и, по-видимому, как и Outlook.
Небольшое предупреждение: если вы используете PHP, вы также можете использовать MySQL. MySQL НЕ следует недельным соглашениям ISO-8601, но делает это достаточно близко, чтобы вы могли подумать, что это так. Как отмечают другие люди в Outlook, пытаться имитировать нестандартный способ вычисления числа недель не стоит!