【问题标题】:What datatype to use for ISO 8601 dates?ISO 8601 日期使用什么数据类型?
【发布时间】:2012-10-19 22:28:36
【问题描述】:

我正在重新设计一个数据库,该数据库当前以2012-10-27T07:30:38+00:00 的格式将 ISO 8601 日期导入 varchar 字段。当前数据库托管在 MySQL 5.5 服务器上。

在搜索文档和各种 SO 帖子时,我还没有找到关于我应该在 MySQL 中为此使用什么数据类型的明确答案。最接近的帖子是:MySQL insert to DATETIME: is it safe to use ISO::8601 format?,它提供了各种解决方法,但这不是一个理想的选择。

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.htmlhttp://www.postgresql.org/docs/9.2/static/datatype-datetime.html),这引出了我的问题:

MySQL 是否正确支持 ISO 8601,还是我应该考虑使用原生支持的数据库?

--编辑--

尝试将上面的示例时间戳插入日期时间列会出现以下错误:

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

【问题讨论】:

  • 由于日期格式问题而切换数据库似乎有点笨拙。您是否尝试过以所需格式插入值?如果是这样,发生了什么? MySQL 在允许的范围内通常非常宽松。
  • @tadman 不是说不是。不过,这次我希望能正确地做事。我的偏好是继续使用 MySQL,但使用正确的数据类型。
  • 不要将时间戳存储在 VARCHAR 列中。绝不。使用原生 timestamp 数据类型并在显示数据时进行格式化。 不要为此使用 varchar
  • TIMESTAMP 列是半神奇的,除非您需要它们,否则不应使用它们。 DATETIME 是通用日期和时间格式,DATE 仅用于日期。
  • @a_horse_with_no_name 因此这个问题:)

标签: mysql postgresql iso8601


【解决方案1】:

不要在 varchar 列中存储日期或时间戳值。您无法确保存储正确的值(没有人阻止您在其中存储 2012-02-31 28:99:70

如果您不需要时间部分,请使用 date 数据类型(在 MySQL 和 PostgreSQL 中可用)如果您确实需要时间使用 timestamp(或在 MySQL 中使用 datetime)数据类型。

值的格式应该在您的前端完成,或者如果您绝对必须在 SQL 中使用例如检索值时的 to_char() (或 MySQL 中的等价物)。

再次重申:永远不要在 varchar 中存储日期或时间戳(就像永远不要在 varchar 列中存储实数一样)。

这里是日期/时间数据类型的 MySQL 概述:http://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html

这里是 date7time 数据类型的 PostgreSQL 概述:http://www.postgresql.org/docs/current/static/datatype-datetime.html

编辑

如果您担心文字格式。两个 DBMS 都支持标准的 ANSI 日期和时间戳文字:

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

用于 PostgreSQL 的 SQLFiddle:http://sqlfiddle.com/#!12/cdd39/1

注意字符文字前面的关键字timestampdate

编辑 2

似乎 MySQL 无法插入这样的值,尽管它可以在 SELECT 语句中使用该文字:

【讨论】:

  • 所以要回答我原来的问题:MySQL 没有用于表达这些值的本机数据类型,为了让它们正确插入,我需要先处理数据?
  • @RobertH:MySQL 确实有一个本地数据类型来存储时间戳:它被称为datetime。不要将存储与展示混淆。
  • 如果我使用 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 部分。如果它是原生的,我不应该从时间戳中删除它。
  • @RobertH: 列date1是什么数据类型@
  • @RobertH: 似乎是 MySQL 的“惊喜”之一。它可以在 SELECT 语句中使用这样的时间戳文字,但显然不能在插入中使用(所以毕竟使用 PostgreSQL 可能会更好......)
【解决方案2】:

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 |
+---------------------+

【讨论】:

    【解决方案3】:

    ISO 8601 日期格式“YYYY-MM-DD”是 MySQL 在显示日期值时在内部发出的格式,它可以同样导入它们。

    这些比“MM/DD/YY”这样的“美式”日期更可取,因为其中有太多的歧义而无法自动解决。

    ISO 9075 似乎指的是整个 SQL 标准,而不是特定的日期格式,尽管该标准本身确实有日期和时间的标准格式。

    【讨论】:

    • 对不起,tadman,我以为我在帖子中放置了一个示例日期/时间字符串,但我没有。你能看看我的编辑吗?
    【解决方案4】:

    使用日期时间或时间戳进行存储的另一个优势。 在 phpMyAdmin 或 phpPgAdmin 中,值显示为字符串,例如2015-01-22 11:13:42。因此,查找日期要容易得多,就像它存储为 varchar 或 int 一样。

    我认为服务器的时区很重要。 我看到 MySql 中的时间戳不显示微秒。 我知道 MySQL 使用 UTC-Time 作为时间戳和日期时间字段。 因此,将值提供为 UTC 时间戳。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 2013-05-14
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      相关资源
      最近更新 更多