【Mysql】The DATE, DATETIME, and TIMESTAMP Types(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 【Mysql】The DATE, DATETIME, and TIMESTAMP Types

Source

dev.mysql.com/doc/refman/…

Mysql 官方文档解释

The DATE, DATETIME, and TIMESTAMP types are related.

DATE"、"DATETIME "和 "TIMESTAMP "类型是相关的。

This section describes their characteristics,  how they are similar, and how they differ. MySQL recognizes DATE, DATETIME, and TIMESTAMP values in several formats, described in Section 9.1.3, “Date and Time Literals”.

本节将介绍它们的特点、相似之处和不同之处。MySQL以几种格式识别DATEDATETIMETIMESTAMP值,在第9.1.3节,"日期和时间字面"中描述。

For the DATE and DATETIME range descriptions, “supported” means that although earlier values might work, there is no guarantee.

对于 DATEDATETIME 范围描述,"支持 "表示虽然早期值可能有效,但不能保证。

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in '_`YYYY-MM-DD`_' format. The supported range is '1000-01-01' to '9999-12-31'.

Date "类型用于包含日期部分但不包含时间部分的值。MySQL 以 '_`YYY-MM-DD`_' 格式检索和显示 DATE 值。支持的范围是1000-01-019999-12-31

The DATETIME type is used for values that contain both date and time parts.

DATETIME "类型用于包含日期和时间部分的值。

MySQL retrieves and displays DATETIME values in '_`YYYY-MM-DD hh:mm:ss`_' format.

MySQL 以YYYY-MM-DD hh:mm:ss格式检索和显示DATETIME值。

The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.

支持的范围是'1000-01-01 00:00:00''9999-12-31 23:59:59'

The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

TIMESTAMP”数据类型用于包含日期和时间部分的值。 “TIMESTAMP”的范围为“1970-01-01 00:00:01”UTC 到“2038-01-19 03:14:07”UTC。

A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision.

数据时间 "或 "时间戳 "值可包括尾部小数秒部分,精度可达微秒(6 位)。

In particular, any fractional part in a value inserted into a DATETIME or TIMESTAMP column is stored rather than discarded.

特别是,插入DATETIMETIMESTAMP列的值中的任何小数部分都会被存储而不是被丢弃。

With the fractional part included, the format for these values is '_`YYYY-MM-DD hh:mm:ss`_[._`fraction`_]', the range for DATETIME values is '1000-01-01 00:00:00.000000' to '9999-12-31 23:59:59.499999', and the range for TIMESTAMP values is '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.499999'.

如果包含小数部分,这些值的格式是 '_`YYY-MM-DD hh:mm:ss`_[._`fraction`_]',

  • DATETIME值的范围是 ``'1000-01-01 00:00:00. 000000''9999-12-31 23:59:59.499999'`
  • TIMESTAMP值的范围是'1970-01-01 00:00:01.000000''2038-01-19 03:14:07.499999'

The fractional part should always be separated from the rest of the time by a decimal point; no other fractional seconds delimiter is recognized.

For information about fractional seconds support in MySQL, see Section 11.2.6, “Fractional Seconds in Time Values”.

The TIMESTAMP and DATETIME data types offer automatic initialization and updating to the current date and time. For more information, see Section 11.2.5, “Automatic Initialization and Updating for TIMESTAMP and DATETIME”.

小数部分应始终用小数点与时间的其余部分分隔;不识别其他小数秒分隔符。有关 MySQL 支持小数秒的信息,请参阅 第 11.2.6 节,"时间值中的小数秒"

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.

MySQL 将 TIMESTAMP 值从当前时区转换到 UTC 以进行存储,并从 UTC 返回到当前时区以进行检索。

(This does not occur for other types such as DATETIME.)

(这不会发生在其他类型,如 DATETIME)。

By default, the current time zone for each connection is the server's time.

默认情况下,每个连接的当前时区是服务器时间。

The time zone can be set on a per-connection basis.

时区可按每个连接设置。

As long as the time zone setting remains constant, you get back the same value you store.

只要时区设置保持不变,就会返回存储的相同值。

If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored.

如果存储了一个 TIMESTAMP 值,然后更改时区并检索该值,检索到的值将与存储的值不同。

This occurs because the same time zone was not used for conversion in both directions.

出现这种情况是因为在两个方向的转换中没有使用相同的时区。

The current time zone is available as the value of the time_zone system variable. For more information, see Section 5.1.15, “MySQL Server Time Zone Support”.

当前时区可作为 time_zone 系统变量的值。更多信息,请参阅第 5.1.15 节,"MySQL 服务器时区支持"

In MySQL 8.0.19 and later, you can specify a time zone offset when inserting a TIMESTAMP or DATETIME value into a table. See Section 9.1.3, “Date and Time Literals”, for more information and examples.

在 MySQL 8.0.19 及更高版本中,在表中插入 TIMESTAMPDATETIME 值时,可以指定时区偏移。更多信息和示例请参阅 第 9.1.3 节 "日期和时间字串"

Invalid DATE, DATETIME, or TIMESTAMP values are converted to the “zero” value of the appropriate type ('0000-00-00' or '0000-00-00 00:00:00'), if the SQL mode permits this conversion.

如果 SQL 模式允许转换,无效的 DATEDATETIMETIMESTAMP 值会被转换为相应类型的 "零 "值('0000-00-00''0000-00-00 00:00:00')。

The precise behavior depends on which if any of strict SQL mode and the NO_ZERO_DATE SQL mode are enabled; see Section 5.1.11, “Server SQL Modes”.

确切的行为取决于启用了严格 SQL 模式和 NO_ZERO_DATE SQL 模式中的哪一种;请参阅 5.1.11 节,"服务器 SQL 模式"

In MySQL 8.0.22 and later, you can convert TIMESTAMP values to UTC DATETIME values when retrieving them using CAST() with the AT TIME ZONE operator, as shown here:

在 MySQL 8.0.22 及更高版本中,使用带有 AT TIME ZONE 操作符的 CAST()检索时,可以将 TIMESTAMP 值转换为 UTC DATETIME 值,如下所示:


mysql> SELECT col,
     >     CAST(col AT TIME ZONE INTERVAL '+00:00' AS DATETIME) AS ut
     >     FROM ts ORDER BY id;
+---------------------+---------------------+
| col                 | ut                  |
+---------------------+---------------------+
| 2020-01-01 10:10:10 | 2020-01-01 15:10:10 |
| 2019-12-31 23:40:10 | 2020-01-01 04:40:10 |
| 2020-01-01 13:10:10 | 2020-01-01 18:10:10 |
| 2020-01-01 10:10:10 | 2020-01-01 15:10:10 |
| 2020-01-01 04:40:10 | 2020-01-01 09:40:10 |
| 2020-01-01 18:10:10 | 2020-01-01 23:10:10 |
+---------------------+---------------------+

For complete information regarding syntax and additional examples, see the description of the CAST() function.

有关语法和其他示例的完整信息,请参阅 CAST() 函数的说明。

Be aware of certain properties of date value interpretation in MySQL:

注意 MySQL 中日期值解释的某些属性:

MySQL permits a “relaxed” format for values specified as strings, in which any punctuation character may be used as the delimiter between date parts or time parts.

对于指定为字符串的值,MySQL 允许使用一种 "宽松 "格式,其中日期部分或时间部分之间可以使用任何标点符号作为分隔符。

In some cases, this syntax can be deceiving.

在某些情况下,这种语法可能具有欺骗性。

For example, a value such as '10:11:12' might look like a time value because of the :, but is interpreted as the year '2010-11-12' if used in date context.

例如,"'10:11:12'"这样的值可能因为": "而看起来像一个时间值,但如果在日期上下文中使用,则会被解释为 年份"'2010-11-12'"

The value '10:45:15' is converted to '0000-00-00' because '45' is not a valid month.

'10:45:15'被转换为'0000-00-00',因为'45'不是有效的月份。

The only delimiter recognized between a date and time part and a fractional seconds part is the decimal point.

日期和时间部分与小数秒钟部分之间的唯一分隔符小数点

The server requires that month and day values be valid, and not merely in the range 1 to 12 and 1 to 31, respectively.

服务器要求月份和日期值必须有效,包括但不限于 1 至 12 和 1 至 31 的范围内。

With strict mode disabled, invalid dates such as '2004-04-31' are converted to '0000-00-00' and a warning is generated.

服务器要求月份和日期值必须有效,包括但不限于 1 至 12 和 1 至 31 的范围内。

With strict mode enabled, invalid dates generate an error.

启用严格模式后,存储无效日期会产生错误。

To permit such dates, enable ALLOW_INVALID_DATES.

要允许此类日期,请启用 ALLOW_INVALID_DATES

  • ALLOW_INVALID_DATESDo not perform full checking of dates. Check only that the month is in the range from 1 to 12 and the day is in the range from 1 to 31. This may be useful for Web applications that obtain year, month, and day in three different fields and store exactly what the user inserted, without date validation. This mode applies to DATE and DATETIME columns. It does not apply to TIMESTAMP columns, which always require a valid date.


如果启用 [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates),则不会对日期进行严格检查。
  非严格模式只检查**月是否在 1 至 12 的范围内,日是否在 1 至 31 的范围内**。这对于在三个不同字段中获取年、月、日,并准确存储用户插入的内容而不进行日期验证的网络应用程序可能很有用。这种模式适用于 [`DATE`](https://dev.mysql.com/doc/refman/8.0/en/datetime.html "11.2.2 日期、数据时间和 TIMESTAMP 类型") 和 [`DATETIME`](https://dev.mysql.com/doc/refman/8.0/en/datetime.html "11.2.2 日期、数据时间和 TIMESTAMP 类型") 列。它不适用于 [`TIMESTAMP`](https://dev.mysql.com/doc/refman/8.0/en/datetime.html "11.2.2 DATE、DATETIME 和 TIMESTAMP 类型") 列,这些列**始终需要有效日期**。
  With [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates) disabled, the server requires that month and day values be legal, and not merely in the range 1 to 12 and 1 to 31, respectively. With strict mode disabled, invalid dates such as `'2004-04-31'` are converted to `'0000-00-00'` and a warning is generated. With strict mode enabled, invalid dates generate an error. To permit such dates, enable [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates).
  如果禁用 [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates),服务器会要求月和日的值必须是合法的,而不只是分别在 1 至 12 和 1 至 31 的范围内。禁用严格模式后,**诸如`'2004-04-31'`之类的无效日期会被转换为`'0000-00-00'`**,并产生警告。启用严格模式后,无效日期会产生错误。
  要允许使用此类日期,请启用 [`ALLOW_INVALID_DATES`](https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_allow_invalid_dates)。

See Section 5.1.11, “Server SQL Modes”, for more information.

更多信息,请参见第 Section 5.1.11, “Server SQL Modes”

  • MySQL does not accept TIMESTAMP values that include a zero in the day or month column or values that are not a valid date.

MySQL 不接受在日或月列中包含零的 TIMESTAMP 值,也不接受不是有效日期的值。

The sole exception to this rule is the special “zero” value '0000-00-00 00:00:00', if the SQL mode permits this value.

这一规则的唯一例外是特殊的 "零 "值'0000-00-00 00:00:00',如果 SQL 模式允许该值的话。

The precise behavior depends on which if any of strict SQL mode and the NO_ZERO_DATE SQL mode are enabled; see Section 5.1.11, “Server SQL Modes”.

具体行为取决于是否启用了严格 SQL 模式NO_ZERO_DATE SQL 模式;请参阅 5.1.11 节,"服务器 SQL 模式"

Dates containing 2-digit year values are ambiguous because the century is unknown. MySQL interprets 2-digit year values using these rules:

包含 2 位数年份值的日期是模糊的,因为世纪不明。MySQL 使用这些规则解释两位数的年份值:

Year values in the range 00-69 become 2000-2069

00-69 "范围内的年份值变为 "2000-2069"。

Year values in the range 70-99 become 1970-1999.

年份范围70-99中的数值变为1970-1999

See also Section 11.2.9, “2-Digit Years in Dates”.

另请参见 第 11.2.9 节,"日期中的两位数年份"

Linux系统如何查看设置所在的时区?

下面是查看设置所在时区的方法:


date -R


[root@localhost alexxander]# date -R
Fri, 21 Jul 2023 16:29:07 -0400

可以看到这里使用的是美国的时区,个人安装Linux系统的时候选择的时区未做修改就会出现这样的情况。

-0400 就是西四区。

那么我们应该如何设置Linux的所在时区?

方法一:使用tzselect设置时区


[root@localhost conf]# tzselect 
Please identify a location so that time zone rules can be set correctly.
Please select a continent or ocean.
 1) Africa
 2) Americas
 3) Antarctica
 4) Arctic Ocean
 5) Asia
 6) Atlantic Ocean
 7) Australia
 8) Europe
 9) Indian Ocean
10) Pacific Ocean
11) none - I want to specify the time zone using the Posix TZ format.
#? 5
Please select a country.
 1) Afghanistan     18) Israel        35) Palestine
 2) Armenia     19) Japan       36) Philippines
 3) Azerbaijan      20) Jordan        37) Qatar
 4) Bahrain     21) Kazakhstan      38) Russia
 5) Bangladesh      22) Korea (North)     39) Saudi Arabia
 6) Bhutan      23) Korea (South)     40) Singapore
 7) Brunei      24) Kuwait        41) Sri Lanka
 8) Cambodia      25) Kyrgyzstan      42) Syria
 9) China     26) Laos        43) Taiwan
10) Cyprus      27) Lebanon       44) Tajikistan
11) East Timor      28) Macau       45) Thailand
12) Georgia     29) Malaysia        46) Turkmenistan
13) Hong Kong     30) Mongolia        47) United Arab Emirates
14) India     31) Myanmar (Burma)     48) Uzbekistan
15) Indonesia     32) Nepal       49) Vietnam
16) Iran      33) Oman        50) Yemen
17) Iraq      34) Pakistan
#? 9
Please select one of the following time zone regions.
1) Beijing Time
2) Xinjiang Time
#? 1
The following information has been given:
  China
  Beijing Time
Therefore TZ='Asia/Shanghai' will be used.
Local time is now:  Sat Jul 22 05:28:59 CST 2023.
Universal Time is now:  Fri Jul 21 21:28:59 UTC 2023.
Is the above information OK?
1) Yes
2) No
#? yes
Please enter 1 for Yes, or 2 for No.
#? 1
You can make this change permanent for yourself by appending the line
  TZ='Asia/Shanghai'; export TZ
to the file '.profile' in your home directory; then log out and log in again.
Here is that TZ value again, this time on standard output so that you
can use the /usr/bin/tzselect command in shell scripts:
Asia/Shanghai

tzselect命令只告诉你选择的时区的写法,并不会生效,我们可以在各种诸如.profile.bash_profile或者/etc/profile中设置正确的TZ环境变量并导出,例如在/etc/profile里面设置 TZ='Asia/Shanghai'

image.png

修改完成之后,我们执行source /etc/profile让配置生效,并且使用date -R查看当前时间:


[root@localhost conf]# date -R
Sat, 22 Jul 2023 05:34:56 +0800

这里发现时间还是存在偏差问题,现在我们要让docker中的Mysql实时同步当前硬件的 clock时间,需要注意的是设置系统时间需要root的权限

hwclock命令用于访问服务器的硬件CMOS时间,无论读取还是设置都需要root权限,例如:


# 获取系统硬件时间
$ sudo hwclock
Fri 23 Jan 2015 03:33:17 PM CST  -0.567492 seconds
# 设置操作系统的软件时间,与系统硬件时间同步
$ sudo hwclock -s
# 设置系统硬件时间,与操作系统的软件时间同步
$ sudo hwclock -w

通过执行hwclock -s,我们可以将Linux设置为一个“近似当前时间”的时间,Linux操作系统维护的软件时间随着服务器的长时间运行会出现漂移,最终会越来越不准确。

方法2:复制相应的时区文件,替换系统时区文件;或者创建链接文件

/usr/share/zoneinfo/下面有很多时区文件,可以复制这些时区文件覆盖/etc/localtime文件,或修改符号链接/etc/locatime对应的文件。


cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime


【Mysql】The DATE, DATETIME, and TIMESTAMP Types(二)https://developer.aliyun.com/article/1395350

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
关系型数据库 MySQL Serverless
MySQL DATETIME 查询条件
MySQL DATETIME 查询条件
52 1
|
4月前
|
关系型数据库 MySQL 数据库
Mysqlbug-Could not create or access the registry key needed for the MySQL applicationto, TIMESTAMP w
Mysqlbug-Could not create or access the registry key needed for the MySQL applicationto, TIMESTAMP w
|
5月前
|
关系型数据库 MySQL
mysql查询结果时间戳转成日期格式——date、DATE_FORMAT和FROM_UNIXTIME的使用
mysql查询结果时间戳转成日期格式——date、DATE_FORMAT和FROM_UNIXTIME的使用
79 0
|
6月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用合集之同步MySQL时,发现Timestamp字段少八个小时,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
6月前
|
SQL 资源调度 关系型数据库
实时计算 Flink版产品使用合集之在抓取 MySQL binlog 数据时,datetime 字段会被自动转换为时间戳形式如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
67 2
|
6月前
|
关系型数据库 MySQL Java
mysql数据库处理TIMESTAMP格式日期
该内容提到了关于MySQL数据库处理TIMESTAMP格式日期的解决方案。首先,引用了两篇CSDN博客文章,一篇是关于使用MyBatis在MySQL中添加或修改TIMESTAMP日期的,另一篇是关于将Oracle的TIMESTAMP字段通过MyBatis插入到数据库的。接着,提到一个错误信息,说明MySQL表中不能有多个TIMESTAMP列。然后,展示了如何设置数据库字段(ctime和mtime)自动记录创建和更新时间,并提供了对应的mapper文件和Java字段定义,以实现业务代码中无需手动设置这些时间戳。
103 2
|
9天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
24 1
|
11天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
26 4
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
61 3
Mysql(4)—数据库索引
|
18天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
85 1