Стандартизация не-совсем-ISO-строк

Задача
Формат даты похож на стандарт ISO, но все же не совсем ему соответствует.

Решение
Стандартизируйте дату, передав ее функции, всегда возвращающей результат в формате даты ISO.

Обсуждение
Ранее в этой главе (см. рецепт 5.8) упоминалось, что при формировании дат с помощью функции CONCAT() можно столкнуться со следующей проблемой: полученное значение может не соответствовать формату ISO. Например, рассмотрим запрос, выводящий значения первого числа месяца, в которых месяц может быть представлен всего одним разрядом:

mysql> SELECT d, CONCAT(YEAR(d),'-',MONTH(d),'-01') FROM date_val;

+------------+------------------------------------+
| d | CONCAT(YEAR(d),'-',MONTH(d),'-01') |
+------------+------------------------------------+
| 1864-02-28 | 1864-2-01 |
| 1900-01-15 | 1900-1-01 |
| 1987-03-05 | 1987-3-01 |
| 1999-12-31 | 1999-12-01 |
| 2000-06-04 | 2000-6-01 |
+------------+------------------------------------+

В рецепте 5.8 было показано, как применять LPAD() для обеспечения двузначности значений месяца:

mysql> SELECT d, CONCAT(YEAR(d),'-',LPAD(MONTH(d),2,'0'),'-01') FROM date_val;

+------------+------------------------------------------------+
| d | CONCAT(YEAR(d),'-',LPAD(MONTH(d),2,'0'),'-01') |
+------------+------------------------------------------------+
| 1864-02-28 | 1864-02-01 |
| 1900-01-15 | 1900-01-01 |
| 1987-03-05 | 1987-03-01 |
| 1999-12-31 | 1999-12-01 |
| 2000-06-04 | 2000-06-01 |
+------------+------------------------------------------------+

Есть еще один способ стандартизации дат, близких к формату ISO, – использование их в выражениях, выводящих ISO-дату.


Для даты d подойдет любое из выражений:

DATE_ADD(d,INTERVAL 0 DAY)
d + INTERVAL 0 DAY
FROM_DAYS(TO_DAYS(d))

Например, преобразуем тремя разными способами в формат ISO не-ISO-результаты выполнения операции CONCAT():

mysql> SELECT d,
-> CONCAT(YEAR(d),'-',MONTH(d),'-01') AS 'non-ISO',
-> DATE_ADD(CONCAT(YEAR(d),'-',MONTH(d),'-01'),INTERVAL 0 DAY) AS method1,
-> CONCAT(YEAR(d),'-',MONTH(d),'-01') + INTERVAL 0 DAY AS method2,
-> FROM_DAYS(TO_DAYS(CONCAT(YEAR(d),'-',MONTH(d),'-01'))) AS method3
-> FROM date_val;

+------------+------------+------------+------------+------------+
| d | non-ISO | method1 | method2 | method3 |
+------------+------------+------------+------------+------------+

| 1864-02-28 | 1864-2-01 | 1864-02-01 | 1864-02-01 | 1864-02-01 |
| 1900-01-15 | 1900-1-01 | 1900-01-01 | 1900-01-01 | 1900-01-01 |
| 1987-03-05 | 1987-3-01 | 1987-03-01 | 1987-03-01 | 1987-03-01 |
| 1999-12-31 | 1999-12-01 | 1999-12-01 | 1999-12-01 | 1999-12-01 |
| 2000-06-04 | 2000-6-01 | 2000-06-01 | 2000-06-01 | 2000-06-01 |
+------------+------------+------------+------------+------------+.



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела MySQL на эту тему:
Выбор записей по временным характеристикам
Вывод значений TIMESTAMP в удобном для чтения виде
Вычисление возраста
Вычисление длины месяца
Вычисление интервалов между значениями времени

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