MySQL DATETIME 数据类型完整指南

在本教程中,您将了解 MySQL DATETIME 数据类型以及如何使用一些方便的函数进行 DATETIME 有效操作。

在 MySQL 中,您使用 DATETIME 来存储包含日期时间的值。当您从 DATETIME 列中查询数据 时,MySQL DATETIME 列的值以下格式显示:

YYYY-MM-DD HH:MM:SS

默认情况下, DATETIME 值范围从 1000-01-01 00:00:009999-12-31 23:59:59

一个 DATETIME 值使用 5 个字节进行存储。此外,一个 DATETIME 值可以包括一个尾随小数秒,格式为: YYYY-MM-DD HH:MM:SS[.fraction]。 例如, 2015-12-20 10:01:00.999999 。当包括小数秒精度时, DATETIME 值需要更多的存储空间,如下表所示:

小数秒精度 存储(字节)
0 0
1、2 1
3、4 2
5、6 3

例如, 2015-12-20 10:01:00.999999 需要 8 个字节,5 个字节用于 2015-12-20 10:01:00 和 3 个字节用于 .999999。 而 2015-12-20 10:01:00.9 只需要 6 个字节,1 个字节用于小数秒精度。

请注意,在 MySQL 5.6.4 之前, DATETIME 值需要 8 个字节的存储空间,而不是 5 个字节。

MySQL 日期时间与时间戳

MySQL 提供了另一种类似于 DATETIME 的 时间数据类型 TIMESTAMP

TIMESTAMP 需要 4 个字节,而 DATETIME 需要 5 个字节。TIMESTAMPDATETIME 二者都需要额外字节存储小数秒。

TIMESTAMP 值范围从 1970-01-01 00:00:01 UTC2038-01-19 03:14:07 UTC 。如果要存储超过 2038 年的时间值,则应使用 DATETIME 代替 TIMESTAMP

MySQL TIMESTAMP 以 UTC 值存储。但是,MySQL 将 DATETIME 值按原样存储,没有时区。让我们看看下面的例子。

首先,将当前连接的时区设置为 +00:00

SET time_zone = '+00:00';

接下来,使用以下语句创建一个表名为 timestamp_n_datetime,该表由两列组成: tsdt 分别是 TIMESTAMPDATETIME 数据类型。

CREATE TABLE timestamp_n_datetime (
    id INT AUTO_INCREMENT PRIMARY KEY,
    ts TIMESTAMP,
    dt DATETIME
);

然后,将当前日期和时间插入 timestamp_n_datetime 表的 tsdt 列中,

INSERT INTO timestamp_n_datetime(ts,dt)
VALUES(NOW(),NOW());

之后,从 timestamp_n_datetime 表中查询数据

SELECT ts, dt
FROM timestamp_n_datetime;
+---------------------+---------------------+
| ts                  | dt                  |
+---------------------+---------------------+
| 2022-03-28 02:52:15 | 2022-03-28 02:52:15 |
+---------------------+---------------------+

DATETIMETIMESTAMP 列中的值都相同。

最后,将连接的时区设置为 +03:00timestamp_n_datetime 再次从表中查询数据。

SET time_zone = '+03:00';

SELECT ts, dt
FROM timestamp_n_datetime;
+---------------------+---------------------+
| ts                  | dt                  |
+---------------------+---------------------+
| 2022-03-28 05:52:15 | 2022-03-28 02:52:15 |
+---------------------+---------------------+

如您所见, TIMESTAMP 列中的值不同。这是因为 TIMESTAMP 当我们更改时区时, TIMESTAMP 列以 UTC 存储日期和时间值,该列的值会根据新时区进行调整。

这意味着如果您使用 TIMESTAMP 数据来存储日期和时间值,则在将数据库移动到位于不同时区的服务器时应该认真考虑。

MySQL 日期时间函数

以下语句使用 NOW() 函数将变量 @dt 设置为当前日期和时间。

SET @dt =  NOW();

要查询 @dt 变量的值,请使用以下 SELECT 语句

SELECT @dt;
+---------------------+
| @dt                 |
+---------------------+
| 2022-03-28 05:56:27 |
+---------------------+

MySQL 日期函数

要从 DATETIME 值中提取日期部分,请按如下方式使用 DATE 函数:

SELECT DATE(@dt);
+------------+
| DATE(@dt)  |
+------------+
| 2022-03-28 |
+------------+

如果您想基于日期查询数据但列中存储的数据基于日期和时间,则此函数非常有用。

让我们看看下面的例子。

CREATE TABLE test_datetime (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at DATETIME
);

INSERT INTO test_datetime(created_at)
VALUES('2015-11-05 14:29:36');

假设您想知道在 2015-11-05 上创建了哪一行。如果您使用以下查询:

SELECT * FROM test_datetime
WHERE created_at = '2015-11-05';

它不返回任何行。

这是因为 created_at 列不仅包含日期,还包含时间。要纠正它,请按如下方式使用 DATE 函数:

SELECT * FROM test_datetime
WHERE DATE(created_at) = '2015-11-05';
+----+---------------------+
| id | created_at          |
+----+---------------------+
|  1 | 2015-11-05 14:29:36 |
+----+---------------------+

它按预期返回一行。如果表中有很多行,MySQL 必须执行全表扫描以定位符合条件的行。

MySQL 时间函数

要从 DATETIME 值中提取时间部分,请使用 TIME 函数作为以下语句:

SELECT TIME(@dt);
+-----------+
| TIME(@dt) |
+-----------+
| 05:56:27  |
+-----------+

MySQL YEAR、QUARTER、MONTH、WEEK、DAY、HOUR、MINUTE 和 SECOND 函数

要从 DATETIME 值中获取年、季度、月、周、日、小时、分钟和秒,请使用以下语句中所示的 YEARQUARTERMONTHWEEKDAYHOURMINUTESECOND 函数:

SELECT
    YEAR(@dt),
    QUARTER(@dt),
    MONTH(@dt),
    WEEK(@dt),
    DAY(@dt),
    HOUR(@dt),
    MINUTE(@dt),
    SECOND(@dt);
+-----------+--------------+------------+-----------+----------+-----------+-------------+-------------+
| YEAR(@dt) | QUARTER(@dt) | MONTH(@dt) | WEEK(@dt) | DAY(@dt) | HOUR(@dt) | MINUTE(@dt) | SECOND(@dt) |
+-----------+--------------+------------+-----------+----------+-----------+-------------+-------------+
|      2022 |            1 |          3 |        13 |       28 |         5 |          56 |          27 |
+-----------+--------------+------------+-----------+----------+-----------+-------------+-------------+

MySQL DATE_FORMAT 函数

要格式化 DATETIME 值,请使用 DATE_FORMAT 函数。例如,以下语句根据 %H:%i:%s - %W %M %Y 格式格式化 DATETIME 值:

SELECT DATE_FORMAT(@dt, '%H:%i:%s - %W %M %Y');
+-----------------------------------------+
| DATE_FORMAT(@dt, '%H:%i:%s - %W %M %Y') |
+-----------------------------------------+
| 05:56:27 - Monday March 2022            |
+-----------------------------------------+

MySQL DATE_ADD 函数

要将间隔添加到 DATETIME 值,请按如下方式使用 DATE_ADD 函数:

SELECT @dt `now`,
       DATE_ADD(@dt, INTERVAL 1 SECOND) `1 second later`,
       DATE_ADD(@dt, INTERVAL 1 MINUTE) `1 minute later`,
       DATE_ADD(@dt, INTERVAL 1 HOUR) `1 hour later`,
       DATE_ADD(@dt, INTERVAL 1 DAY) `1 day later`,
       DATE_ADD(@dt, INTERVAL 1 WEEK) `1 week later`,
       DATE_ADD(@dt, INTERVAL 1 MONTH) `1 month later`,
       DATE_ADD(@dt, INTERVAL 1 YEAR) `1 year later`\G
*************************** 1. row ***************************
           now: 2022-03-28 05:56:27
1 second later: 2022-03-28 05:56:28
1 minute later: 2022-03-28 05:57:27
  1 hour later: 2022-03-28 06:56:27
   1 day later: 2022-03-29 05:56:27
  1 week later: 2022-04-04 05:56:27
 1 month later: 2022-04-28 05:56:27
  1 year later: 2023-03-28 05:56:27

MySQL DATE_SUB 函数

要从一个 DATETIME 值中减去一个区间,请按如下方式使用 DATE_SUB 函数:

SELECT @dt `now`,
       DATE_SUB(@dt, INTERVAL 1 SECOND) `1 second before`,
       DATE_SUB(@dt, INTERVAL 1 MINUTE) `1 minute before`,
       DATE_SUB(@dt, INTERVAL 1 HOUR) `1 hour before`,
       DATE_SUB(@dt, INTERVAL 1 DAY) `1 day before`,
       DATE_SUB(@dt, INTERVAL 1 WEEK) `1 week before`,
       DATE_SUB(@dt, INTERVAL 1 MONTH) `1 month before`,
       DATE_SUB(@dt, INTERVAL 1 YEAR) `1 year before`\G
*************************** 1. row ***************************
            now: 2022-03-28 05:56:27
1 second before: 2022-03-28 05:56:26
1 minute before: 2022-03-28 05:55:27
  1 hour before: 2022-03-28 04:56:27
   1 day before: 2022-03-27 05:56:27
  1 week before: 2022-03-21 05:56:27
 1 month before: 2022-02-28 05:56:27
  1 year before: 2021-03-28 05:56:27

MySQL DATE_DIFF 函数

要计算两个 DATETIME 值之间的天数差异,请使用 DATEDIFF 函数。请注意, DATEDIFF 函数在计算中仅考虑 DATETIME 值的日期部分。

SELECT DATEDIFF(@dt, '2022-01-01');
+-----------------------------+
| DATEDIFF(@dt, '2022-01-01') |
+-----------------------------+
|                          86 |
+-----------------------------+

结论

在本教程中,您学习了 MySQL DATETIME 数据类型和一些有用的 DATETIME 函数。

  • DATETIME 值包含日期和时间,也可以包含小数秒。
  • DATETIME 值的格式为 YYYY-MM-DD HH:MM:SS
  • DATETIME 值不包含时区信息。