Вопрос по date, mysql – Неделя года на недели, начинающиеся с субботы

2

У нас есть клиенты, у которых в настоящее время определены недели, начиная с субботы, воскресенья или понедельника. Наткнулся на эти опции DATE_FORMAT, которые прекрасно справляются с неделей, начинающейся в воскресенье и понедельник, но не могут найти способ сделать то же самое для недели, начинающейся в субботу. Какие-либо предложения?

%U    Week (00..53), where Sunday is the first day of the week
%u    Week (00..53), where Monday is the first day of the week

Ваш Ответ

3   ответа
0

Сделать корректировку на основеDAYOFWEEK().

2

Мне понадобилось время, чтобы подумать над этим вопросом.

Стандарт ИСО определяет первую неделю, которая начинается в понедельник и содержит 4-й день года. Функции MySQL обеспечиваютгораздо больше вариантов.

date_format() флаги%U а также%u используют обозначение, где первая неделя - это та, где воскресенье или понедельник встречаются впервые. Поскольку это не соответствует ISO, я предоставлю оба варианта.

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

SELECT sign(dayofweek(current_date) - 7) + ceil(dayofyear(current_date)/7);
SELECT ceil((dayofyear(current_date)+
            (dayofweek(date_format(current_date, '%Y-01-01'))%7-7))/7);

Если первая годовая неделя относится к четвертому дню года, используйте:

SELECT ceil((dayofyear(current_date)+
            (dayofweek(date_format(current_date, '%Y-01-04'))%7-4+1))/7);

Самое первое выражение довольно простое.

Я подробно остановлюсь на втором и третьем. Я рассчитываю номер недели, беря текущий день года, делив его на 7 и потолочно, довольно просто. Номер недели должен быть скорректирован в зависимости от ситуации в начале года.

  • for the first case (first week starts with the first Saturday), I take day-of-week for the Jan/1 of the year in subject, make Saturday as the day 0 and then adjust day-of-year by the difference. This this makes all days before first saturday yielding negative adjustment number and it ceils up to zero;
  • for the second case (first week is the one where 4 day of the year falls in), I take day-of-week for the Jan/4 of the year in subject, make Saturday as the day 0. The -4+1 formula gives adjustment to the first Saturday before Jan/4, +1 is used as days of the year starts from 1, not from 0. Negative adjustment means 1st day of the year is not in the first week of the year.

Вот некоторые даты испытаний наSQL Fiddle.

Если вы хотите считать недели от любого другого дня, вам просто нужно изменить формулу, чтобы этот день был0 в последовательности. Скажем, чтобы считать недели, начиная со среды, используйте:

SELECT ceil((dayofyear(current_date)+
    ((dayofweek(date_format(current_date, '%Y-01-04'))+3)%7-4+1))/7);

+3 используется как дополнениеdayofweek() значение для среды до 7.

3

У меня была похожая проблема: мне нужно было рассчитать номера недель на основе следующих правил:

  • Week starts on Friday
  • The remainder days of an year (all the days after the last Friday of the year that do not complete a week) should be counted in the first week of the next year.

Например:

  • 27/12/2012 (Thursday) should be Week 52 of 2012
  • 28/12/2012 (Friday) should be Week 1 of 2013
  • Week 1 2013 goes from 28/12/2012 to 3/1/2013

Я сделал это утверждение, которое вычисляет как ГОД, так и НЕДЕЛЮ на основе этих правил, которые вы можете легко адаптировать к своему обстоятельству:

SELECT IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, YEAR(current_date)+1, YEAR(current_date)), 
        IF(ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7) > 52, 1, ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7));

Сложная часть - вот это выражение:

ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+1 )/7)

Остальные (предложения If) предназначены только для адаптации результата выражения, чтобы сделать год + 1 и неделю = 1 на неделе 53.

Я постараюсь объяснить это выражение как можно лучше. Следующее выражение дает вам номер недели в чистом виде (день года делится на 7 дней в неделю с округлением в большую сторону):

ceil(( dayofyear(current_date))/7)

Но теперь вы хотите, чтобы это началось в пятницу (или в любой другой день). Для этого вам нужно добавить к текущему дню дни первой недели, которые были частью предыдущего года (это похоже на то, что ваш текущий день фактически начался несколькими днями ранее, потому что ваша первая неделя содержит дни предыдущего года) , Это выражение вычисляет это смещение на основе дня недели января / 1:

dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET

Смещение - это разница между 7 и номером дня недели, для которого вы хотите начать неделю:

  • 0 for Saturday
  • 1 for Friday
  • 2 for Thursday
  • 3 for Wednesday ...

Так что теперь вам просто нужно добавить его к предыдущему, в результате чего появится вышеупомянутое выражение, которое вычисляет номера недель, начиная с любого дня недели и предполагая, что неделя 1 начинается с предыдущего года:

ceil(( dayofyear(current_date) + dayofweek(date_format(current_date, '%Y-01-01'))+OFFSET )/7)

Затем я просто добавил IF, который превращает 53-ю неделю в 1-ю неделю, а другой - в 1, если это 53-я неделя.

Похожие вопросы