MySQL.RU .:. Одобрено лучшими российскими программистами

Справочное руководство по MySQL

1.4.5 Вопросы, связанные с Проблемой-2000

1.4.5 Вопросы, связанные с Проблемой-2000

Сам MySQL не имеет проблем, связанных с Проблемой-2000 (Y2K):

  • В MySQL используются функции времени Unix, поэтому проблемы с датами, вплоть до 2069, исключены. Принимается, что все двузначные значения годов находятся в диапазоне с 1970 по 2069, поэтому число 01 в столбце с типом year MySQL обрабатывает как 2001.
  • Все MySQL-функции, обрабатывающие даты, хранятся в одном файле `sql/time.cc'. Их код был написан очень тщательно, чтобы застраховаться от проблем, связанных с 2000-м годом.
  • В версиях MySQL 3.22 и более поздних в столбцах с новым типом YEAR, который обеспечивает хранение нулевого 0 года и значений лет от 1901 до 2155 в одном байте, а также отображение дат при помощи 2 или 4 знаков.

Проблемы, связанные с 2000-м годом, могут возникнуть в приложениях, которые используют MySQL так, что это может оказаться небезопасным с точки зрения Y2K. Например, во многих старых приложениях для хранения и обработки значений годов используются 2-значные величины (которые можно трактовать неоднозначно), а не 4-значные. Эта проблема может быть урегулирована при помощи приложений, которые используют 00 или 99 как ``отсутствующие'' индикаторы значений.

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

Приведенный ниже код является наглядной демонстрацией того, что в MySQL Server проблемы с датами вплоть до 2030 года отсутствуют.

mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE y2k (date DATE,
    -> date_time DATETIME,
    -> time_stamp TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO y2k VALUES
    -> ("1998-12-31","1998-12-31 23:59:59",19981231235959),
    -> ("1999-01-01","1999-01-01 00:00:00",19990101000000),
    -> ("1999-09-09","1999-09-09 23:59:59",19990909235959),
    -> ("2000-01-01","2000-01-01 00:00:00",20000101000000),
    -> ("2000-02-28","2000-02-28 00:00:00",20000228000000),
    -> ("2000-02-29","2000-02-29 00:00:00",20000229000000),
    -> ("2000-03-01","2000-03-01 00:00:00",20000301000000),
    -> ("2000-12-31","2000-12-31 23:59:59",20001231235959),
    -> ("2001-01-01","2001-01-01 00:00:00",20010101000000),
    -> ("2004-12-31","2004-12-31 23:59:59",20041231235959),
    -> ("2005-01-01","2005-01-01 00:00:00",20050101000000),
    -> ("2030-01-01","2030-01-01 00:00:00",20300101000000),
    -> ("2050-01-01","2050-01-01 00:00:00",20500101000000);
Query OK, 13 rows affected (0.01 sec)
Records: 13 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM y2k;
+------------+---------------------+----------------+
| date | date_time | time_stamp |
+------------+---------------------+----------------+
| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
| 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 |
+------------+---------------------+----------------+
13 rows in set (0.00 sec)

Можно видеть, что при использовании типов DATE и DATETIME проблем с датами будущего не возникнет (эти типы ``справляются'' с датами вплоть до 9999 года).

Тип TIMESTAMP, который используется для сохранения текущего времени, имеет диапазон только до 2030-01-01. В 32-разрядных машинах TIMESTAMP тип имеет диапазон от 1970 до 2030 (значение со знаком). В 64-разрядных машинах этот тип ``справляется'' со значениями времени до 2106 года (значение без знака).

Таким образом, даже несмотря на то, что MySQL является Y2K-совместимым, ответственность за однозначную интерпретацию значений даты ложится на плечи пользователя. See section 6.2.2.1 Проблема 2000 года и типы данных, где приведены правила по работе MySQL с входными данными, которые имеют неоднозначные значения даты (данные, содержащие 2-значные значения года).