MySQL / 5. Работа с датами и временем

Определение дат для дней текущей недели

Задача
Вы хотите узнать дату какого-то дня текущей недели.

Решение
Вычислите количество дней между началом недели и интересующим вас днем и сдвиньте дату на полученное значение.

Обсуждение
В этом и следующем разделах рассказано о том, как преобразовывать одну дату в другую при условии, что дата, которую нужно получить, указана в терминах дней недели. Например, если вы хотите узнать, каким числом будет вторник на этой неделе, то все зависит от того, какой день недели сегодня. Если сегодня понедельник, следует прибавить день к CURDATE(), если же сегодня среда, необходимо вычесть один день.MySQL содержит две полезные функции. DAYOFWEEK() считает началом недели воскресенье и возвращает значения от 1 до 7 для дней недели, начиная с воскресенья и заканчивая субботой. Функция WEEKDAY() воспринимает понедельник как начало недели и возвращает значения от 0 до 6 для дней с понедельника по воскресенье (в примерах будет использоваться DAYOFWEEK()).

Можно получать не номера дней недели, а их названия, – этим занимается DAYNAME(). Вычисления, определяющие один день недели на основе другого, зависят как от исходного значения, так и от конечного. Мне кажется, что проще всего сначала сместить начальную дату в точку, положение которой относительно начала недели зафиксировано, а затем выполнить обратное смещение:

• Сдвиньте исходную дату назад на количество дней, равное ее значению DAYOFWEEK(), в результате чего вы всегда получите дату субботы предыдущей недели.

• Добавьте один день, чтобы получить дату воскресенья, два дня, чтобы получить дату понедельника и т. д.

В SQL для получения дат дней с воскресенья по субботу для исходной даты d можно выполнить такую операцию (где n равно от 1 до 7):

DATE_ADD(DATE_SUB(d,INTERVAL DAYOFWEEK(d) DAY),INTERVAL n DAY)

Выражение выделяет сдвиг к субботе и обратный сдвиг в отдельные операции, но поскольку интервалы DATE_SUB()и DATE_ADD() измеряются в днях, можно упростить выражение, используя только вызов DATE_ADD():

DATE_ADD(d,INTERVAL n-DAYOFWEEK(d) DAY)

Применим этот прием к таблице date_val, используя значение n, равное 1 для воскресенья и 7 – для субботы, для нахождения первого и последнего дней недели:

mysql> SELECT d, DAYNAME(d) AS day,
-> DATE_ADD(d,INTERVAL 1-DAYOFWEEK(d) DAY) AS Sunday,
-> DATE_ADD(d,INTERVAL 7-DAYOFWEEK(d) DAY) AS Saturday
-> FROM date_val;

+--------------+-----------+--------------+---------------+
|          d         |      day    |     Sunday   |    Saturday   |
+--------------+-----------+--------------+----v----------+
| 1864-02-28 |   Sunday | 1864-02-28 | 1864-03-05 |
| 1900-01-15 |   Monday | 1900-01-14 | 1900-01-20 |
| 1987-03-05 | Thursday | 1987-03-01 | 1987-03-07 |
| 1999-12-31 |    Friday   | 1999-12-26 | 2000-01-01 |
| 2000-06-04 |   Sunday  | 2000-06-04 | 2000-06-10 |
+--------------+------------+--------------+---------------+

Статьи по MySQL на эту тему:

Выбор записей по временным характеристикам
Вывод значений TIMESTAMP в удобном для чтения виде
Вычисления для високосных годов
Вычисления со значениями TIMESTAMP Задача
Использование значений TIMESTAMP

Вернуться в раздел: MySQL / 5. Работа с датами и временем