Какой тип данных использовать для дат ISO 8601?

Я переделываю базу данных, которая в настоящее время импортирует даты ISO 8601 в формате 2012-10-27T07:30:38+00:00 в поле varchar. Текущая база данных размещена на сервере MySQL 5.5.

При поиске в документации и различных сообщениях SO я не нашел однозначного ответа о том, какой тип данных мне следует использовать в MySQL для этой цели. Ближайшее сообщение: MySQL вставить в DATETIME: безопасно ли использовать формат ISO :: 8601?, где он обеспечивает своего рода обходной путь, однако это нежелательный вариант.

Документация MySQL (http://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html) не говорит, и единственная ссылка, которую я могу найти в официальной документации, находится на странице: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html

в котором говорится: «Возможные значения для первого и второго аргументов приводят к нескольким возможным строкам формата (используемые спецификаторы см. в таблице в описании функции DATE_FORMAT ()). Формат ISO относится к ISO 9075, а не к ISO 8601.»

Теперь в документации PostgreSQL специально упоминается ISO8601 (http://www.postgresql.org/docs/9.2/static/datetime-keywords.html и http://www.postgresql.org/docs/9.2/static/datatype-datetime.html), что подводит меня к моему вопросу:

Правильно ли MySQL поддерживает ISO 8601, или мне следует рассмотреть базу данных с встроенной поддержкой?

--Редактировать--

Попытка вставить примерную отметку времени выше в столбец datetime дает следующую ошибку:

10:55:55    insert into test(date1) values('2012-10-27T07:30:38+00:00') Error Code: 1292. Incorrect datetime value: '2012-10-27T07:30:38+00:00' for column 'date1' at row 1 0.047 sec

person Robert H    schedule 30.10.2012    source источник
comment
Переключение базы данных из-за проблемы с форматированием даты кажется немного неуклюжим. Вы пробовали вставлять значения в желаемый формат? Если да, то что случилось? MySQL обычно довольно расслаблен с точки зрения того, что он позволяет.   -  person tadman    schedule 30.10.2012
comment
@tadman Я не говорю, что это не так. Но на этот раз я постараюсь сделать все как следует. Я предпочитаю оставаться с MySQL, но использовать правильные типы данных.   -  person Robert H    schedule 30.10.2012
comment
НЕ храните отметки времени в столбцах VARCHAR. Никогда. Используйте собственный тип данных timestamp и выполняйте форматирование при отображении данных. Не используйте для этого varchar   -  person a_horse_with_no_name    schedule 30.10.2012
comment
TIMESTAMP столбцы являются полумагическими, и их не следует использовать, если они вам не нужны. DATETIME - это общий формат даты и времени или DATE только для даты.   -  person tadman    schedule 30.10.2012
comment
@a_horse_with_no_name отсюда этот вопрос :)   -  person Robert H    schedule 30.10.2012
comment
@tadman: тип данных PostgreSQL timestamp не имеет магического поведения и соответствует типу данных MySQL datetime (хотя и с более высокой точностью)   -  person a_horse_with_no_name    schedule 30.10.2012
comment
Еще одно предостережение: TIMESTAMP более ограничен с точки зрения допустимого времени, и первый из этих столбцов будет автоматически установлен на текущее время при вставке строки, если явно не указано значение, отличное от NULL.   -  person tadman    schedule 30.10.2012


Ответы (4)


Не храните значения даты или времени в столбце varchar. У вас нет возможности гарантировать сохранение правильного значения (никто не мешает вам сохранить там 2012-02-31 28:99:70.

Если вам не нужна временная часть, используйте тип данных date (доступен в MySQL и PostgreSQL), если вам действительно нужно время, используйте тип данных timestamp (или datetime в MySQL).

Форматирование значений должно выполняться в вашем интерфейсе или, если вам абсолютно необходимо сделать это в SQL, например, to_char () (или эквивалент в MySQL) при получении значений.

Опять же: никогда не храните даты или временные метки в varchar (точно так же, как вы никогда не должны хранить действительные числа в столбце varchar).

Вот обзор MySQL для типов данных дата / время: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html

Вот обзор PostgreSQL для типов данных date7time: http://www.postgresql.org/docs/current/static/datatype-datetime.html.

Изменить

Если вас беспокоит буквальный формат. Обе СУБД поддерживают стандартные литералы даты и времени ANSI:

insert into some_table 
   (ts_column, date_column)
values
   (timestamp '2012-10-27T07:30:38+00:00', DATE '2012-12-30');

SQLFiddle для PostgreSQL: http://sqlfiddle.com/#!12/cdd39/1

Обратите внимание на ключевые слова timestamp и date перед символьным литералом.

Изменить 2

Кажется, MySQL не может вставить такое значение, хотя он может использовать этот литерал в операторе SELECT:

person a_horse_with_no_name    schedule 30.10.2012
comment
Итак, чтобы ответить на мой исходный вопрос: MySQL не имеет собственного типа данных для выражения этих значений, и для того, чтобы заставить их правильно вставить, мне нужно сначала обработать данные? - person Robert H; 30.10.2012
comment
@RobertH: MySQL действительно имеет собственный тип данных для хранения метки времени: он называется datetime. Не путайте память с дисплеем. - person a_horse_with_no_name; 30.10.2012
comment
Если я использую тип данных datetime, я получаю сообщение об ошибке в отредактированном сообщении: Error Code: 1292. Incorrect datetime value: '2012-10-27T07:30:38+00:00' for column 'date1' at row 1 0.047 sec Проблема заключается в +00:00 разделе предоставленных временных меток. Если бы он был родным, мне не пришлось бы удалять его из метки времени. - person Robert H; 30.10.2012
comment
@RobertH: какой тип данных столбец date1 - person a_horse_with_no_name; 30.10.2012
comment
date1 - это datetime, я также пробовал использовать временную метку с аналогичными результатами - person Robert H; 30.10.2012
comment
@RobertH: похоже, это одна из тех MySQL-сюрпризов. Он может использовать такой литерал временной метки в операторе SELECT, но, по-видимому, не во вставке (так что, в конце концов, вам действительно может быть лучше использовать PostgreSQL ...) - person a_horse_with_no_name; 30.10.2012
comment
Я благодарен вам за то, что вы нашли время изучить это - я думаю, что могу перекусить и переключиться - слишком большая часть наших данных чувствительна к дате и времени, чтобы поиграть с данными до того, как они будут добавлены. - person Robert H; 30.10.2012
comment
@RobertH: PostgreSQL имеет гораздо больше преимуществ, чем просто лучшая обработка временных меток;) - person a_horse_with_no_name; 30.10.2012

Postgresql может обрабатывать этот формат:

без

select timestamp '2012-10-27T07:30:38+00:00';
      timestamp      
---------------------
 2012-10-27 07:30:38

или с часовым поясом:

select timestamptz '2012-10-27T07:30:38+00:00';
      timestamptz       
------------------------
 2012-10-27 05:30:38-02

В то время как MySQL, похоже, не очень заботится о части часового пояса:

create table t (ts timestamp);

insert into t (ts) values
('2012-10-27T07:30:38+03:00'),
('2012-10-27T07:30:38-02:00');

select * from t;
+---------------------+
| ts                  |
+---------------------+
| 2012-10-27 07:30:38 |
| 2012-10-27 07:30:38 |
+---------------------+
person Clodoaldo Neto    schedule 30.10.2012

Еще одно преимущество использования даты и времени или метки времени для хранения. В phpMyAdmin или phpPgAdmin значение отображается в виде строки, например. 2015-01-22 11:13:42. Так что гораздо проще найти дату, как если бы она хранится как varchar или int.

И я думаю, что важно, какой часовой пояс у сервера. Я видел, что метка времени в MySql не отображает микросекунды. Я знаю, что MySQL использует UTC-Time для полей timestamp и datetime. Поэтому укажите значения в виде отметки времени в формате UTC.

person Alexander Behling    schedule 22.01.2015

Формат даты ISO 8601, «ГГГГ-ММ-ДД», - это то, что MySQL выдает внутри при отображении значения даты, и он может импортировать их точно так же.

Они предпочтительнее дат в "американском стиле", таких как "ММ / ДД / ГГ", где слишком много двусмысленностей, чтобы их можно было автоматически разрешить.

ISO 9075, по-видимому, относится ко всему стандарту SQL, а не к конкретному формату даты, хотя сам стандарт имеет стандартное форматирование даты и времени.

person tadman    schedule 30.10.2012
comment
Прошу прощения, tadman, я думал, что поместил пример строки даты / времени в свой пост, но я этого не сделал. Вы можете увидеть мою редакцию. - person Robert H; 30.10.2012