我应该在MySQL中使用日期时间或时间戳数据类型吗?

你会推荐使用datetime时间戳字段吗?为什么(使用MySQL)?

我在服务器端使用PHP。

1068586 次浏览

在使用MySQL和PHP时,我总是使用Unix时间戳。这是PHP中默认的日期方法使用时间戳作为参数的主要原因,因此不需要解析。

要在PHP中获取当前的Unix时间戳,只需time();
在MySQL中,SELECT UNIX_TIMESTAMP();.

timestamp字段是datetime字段的特例。您可以创建timestamp列以具有特殊属性;它可以设置为在创建和/或更新时自行更新。

在“更大”的数据库术语中,timestamp上有几个特殊情况的触发器。

什么是正确的完全取决于你想做什么。

MySQL中的时间戳通常用于跟踪记录的更改,并且通常在每次记录更改时更新。如果您想存储特定值,您应该使用日期时间字段。

如果您的意思是要在使用UNIX时间戳还是本机MySQL日期时间字段之间做出决定,请使用本机DATETIME格式。您可以以这种方式在MySQL中进行计算("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)"),如果您想使用PHP对记录进行操作,则可以在查询记录时将值的格式更改为UNIX时间戳("SELECT UNIX_TIMESTAMP(my_datetime)")

我在语义基础上做出这个决定。

当我需要记录(或多或少)固定时间点时,我使用时间戳。例如,当记录插入数据库或发生某些用户操作时。

当日期/时间可以任意设置和更改时,我使用日期时间字段。例如,当用户可以保存以后的更改约会时。

除了行元数据(创建或修改的日期)之外,我总是使用DATETIME字段。

提到在MySQL留档:

当您需要同时包含日期和时间信息的值时,使用DATETIME类型。MySQL以'YYYY-MM-DD HH: MM: SS'格式检索和显示DATETIME值。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。

TIMESTAMP数据类型的范围为'1970-01-01 00:00:01'UTC到'2038-01-09 03:14:07'UTC。它具有不同的属性,具体取决于MySQL版本和服务器运行的SQL模式。

您很可能会达到常规使用的TIMESTAMP的下限-例如存储生日。

我更喜欢使用时间戳,以便将所有内容保持在一种通用的原始格式中,并将数据格式化为PHP代码或SQL查询中。

TIMESTAMP为4字节,而DATETIME为8字节。

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

但就像scronide说的,它确实有1970年的下限。不过,这对未来可能发生的任何事情都很好;)

在MySQL 5及更高版本中,TIMESTAMP值从当前时区转换为UTC以进行存储,然后从UTC转换回当前时区以进行检索。(这仅适用于TIMESTAMP数据类型,没有适用于其他类型,例如DATETIME。)

默认情况下,每个连接的当前时区是服务器的时间。时区可以在每个连接的基础上设置,如MySQL服务器时区支持所述。

主要区别在于DATETIME是常量,而TIMESTAMP受time_zone设置的影响。

因此,只有当您已经-或者将来可能已经-跨时区同步集群时,它才重要。

简单地说:如果我在澳大利亚有一个数据库,并转储该数据库以同步/填充美国的数据库,那么TIMESTAMP将更新以反映新时区中事件的实时时间,而DATETIME仍将反映au时区中事件的时间

使用TIMESTAMP的地方使用DATETIME的一个很好的例子是在Facebook上,他们的服务器永远不会确定跨时区发生的时间。有一次,我在一次对话中,时间说我正在回复消息,而消息实际发送之前。(当然,如果时间是发布的,而不是同步的,这也可能是由于消息传递软件中的时区转换不好造成的。)

TIMESTAMP始终以UTC为单位(即,自1970-01-01以来经过的秒,以UTC为单位),您的MySQL服务器会将其自动转换为连接时区的日期/时间。从长远来看,TIMESTAMP是可行的方法,因为您知道您的时间数据将始终以UTC为单位。例如,如果您迁移到不同的服务器或更改服务器上的时区设置,您不会搞砸日期。

注意:默认连接时区是服务器时区,但这可以(应该)在每个会话中更改(参见SET time_zone = ...)。

取决于应用程序,真的。

考虑将用户的时间戳设置到纽约的服务器,以便在Sanghai进行约会。现在,当用户在Sanghai连接时,他会从东京的镜像服务器访问相同的约会时间戳。他将看到东京时间的约会,与原始纽约时间偏移。

因此,对于表示用户时间的值(如约会或日程安排),datetime更好。它允许用户控制所需的确切日期和时间,而不管服务器设置如何。设置时间是设置时间,不受服务器时区、用户时区或夏令时计算方式的更改(是的,它确实会更改)的影响。

另一方面,对于表示系统时间的值,如支付事务、表修改或日志记录,始终使用时间戳。将服务器移动到另一个时区或在不同时区的服务器之间进行比较时,系统不会受到影响。

时间戳在数据库上也更轻,索引更快。

我喜欢Unix时间戳,因为你可以转换为数字,只关心数字。加上你加/减和获得持续时间等。然后将结果转换为任何格式的日期。此代码找出文档中的时间戳和当前时间之间传递的时间(以分钟为单位)。

$date  = $item['pubdate']; (etc ...)$unix_now = time();$result = strtotime($date, $unix_now);$unix_diff_min = (($unix_now  - $result) / 60);$min = round($unix_diff_min);

下面的示例显示了TIMESTAMP日期类型如何在更改time-zone to 'america/new_york'后更改值,其中DATETIME未更改。

mysql> show variables like '%time_zone%';+------------------+---------------------+| Variable_name    | Value               |+------------------+---------------------+| system_time_zone | India Standard Time || time_zone        | Asia/Calcutta       |+------------------+---------------------+
mysql> create table datedemo(-> mydatetime datetime,-> mytimestamp timestamp-> );
mysql> insert into datedemo values ((now()),(now()));
mysql> select * from datedemo;+---------------------+---------------------+| mydatetime          | mytimestamp         |+---------------------+---------------------+| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |+---------------------+---------------------+
mysql> set time_zone="america/new_york";
mysql> select * from datedemo;+---------------------+---------------------+| mydatetime          | mytimestamp         |+---------------------+---------------------+| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |+---------------------+---------------------+

我已经将我的答案转换为文章,以便更多的人可以发现这很有用,MySQL: Datetime Versus Timestamp Data Types

我发现TIMESTAMP在不使用不必要的触发器的情况下根据当前时间自动更新自身的能力具有无与伦比的有用性。

它可以跟踪不同的时区,因此如果您需要显示相对时间,UTC时间就是您想要的。

我总是使用Unix时间戳,只是为了在处理大量日期时间信息时保持理智,尤其是在执行时区调整、添加/减去日期等时。在比较时间戳时,这排除了时区的复杂因素,并允许您在服务器端处理中节省资源(无论是应用程序代码还是数据库查询),因为您使用轻量级算术而不是更重的日期时间添加/减法函数。

还有一件事值得考虑:

如果你正在构建一个应用程序,你永远不知道你的数据将如何被使用。如果你最终不得不比较数据集中的一堆记录,比如说,一堆来自第三方API的项目,然后说,按时间顺序排列,你会很高兴为你的行提供Unix时间戳。即使你决定使用MySQL时间戳,也存储一个Unix时间戳作为保险。

值得注意的是,在MySQL中,您可以在创建表列时使用以下内容:

on update CURRENT_TIMESTAMP

这将更新您修改行的每个实例的时间,有时对存储的上次编辑信息非常有帮助。这仅适用于时间戳,但不适用于日期时间。

根据我的经验,如果您想要一个日期字段,其中插入只发生一次,并且您不希望对该特定字段进行任何更新或任何其他操作,请使用日期时间

例如,考虑具有注册日期字段的user表。在该user表中,如果您想知道特定用户的上次登录时间,请使用时间戳类型的字段,以便更新该字段。

如果您从phpMyAdmin创建表,则默认设置将在发生行更新时更新时间戳字段。如果您提交的时间戳未通过行更新进行更新,您可以使用以下查询使时间戳字段自动更新。

ALTER TABLE your_tableMODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

时间戳数据类型存储日期和时间,但以UTC格式存储,而不是像datetime那样以当前时区格式存储。当您获取数据时,时间戳再次将其转换为当前时区时间。

因此,假设您在美国并从具有美国时区的服务器获取数据。然后您将根据美国时区获得日期和时间。时间戳数据类型列总是在其行更新时自动更新。因此,跟踪上次更新特定行的时间会很有用。

有关更多详细信息,您可以阅读博客文章时间戳与日期时间

当您对表执行UPDATE语句时,请注意更改时间戳。如果您有一个包含“名称”(varchar)、“年龄”(int)和“Date_Added”(时间戳)列的表,并且您运行以下DML语句

UPDATE tableSET age = 30

然后,“Date_Added”列中的每个值都将更改为当前时间戳。

  1. TIMESTAMP是4个字节,DATETIME是8个字节。

  2. 时间戳在数据库上也更轻,索引更快。

  3. 当您需要同时包含日期和时间信息的值时,使用DATETIME类型。MySQL以YYYY-MM-DD HH:MM:SS格式检索和显示DATETIME值。支持的范围是1000-01-01 00:00:009999-12-31 23:59:59TIMESTAMP数据类型的范围是1970-01-01 00:00:01 UTC2038-01-09 03:14:07 UTC。它具有不同的属性,具体取决于MySQL版本和服务器运行的SQL模式。

  4. DATETIME是常数,而TIMESTAMPtime_zone设置的影响。

时间戳和日期时间之间的另一个区别是时间戳不能默认值为NULL。

主要区别在于

  • 时间戳上的索引-有效
  • 日期时间上的索引-不起作用

看看这个发布以查看Datetime索引的问题

我建议使用也没有作为DATETIME或TIMESTAMP字段。如果您想将特定的一天作为一个整体表示(例如生日),请使用DATE类型,但如果您比DATE类型更具体,您可能会对记录实际时刻而不是时间单位(日,周,月,年)感兴趣。使用BIGINT而不是使用DATETIME或TIMESTAMP,并简单地存储自纪元以来的毫秒数(System.currentTimeMillis(),如果您使用Java)。这有几个优点:

  1. 你避免了厂商锁定。几乎每个数据库都以相对相似的方式支持整数。假设你想移动到另一个数据库。你想担心MySQL的DATETIME值之间的差异以及Oracle如何定义它们吗?即使在不同版本的MySQL中,TIMESTAMPS也有不同的精度级别。直到最近,MySQL才支持时间戳中的毫秒。
  2. 没有时区问题。关于不同数据类型的时区会发生什么,这里有一些有见地的评论。但是这是常识吗?你的同事都会花时间学习吗?另一方面,很难把BigINT改成java.util.日期。使用BIGINT会导致很多时区问题被搁置。
  3. 不用担心范围或精度。您不必担心未来的日期范围会缩短什么(TIMESTAMP仅适用于2038年)。
  4. 第三方工具集成。通过使用整数,第三方工具(例如Eclipse Link)与数据库的接口很简单。并非每个第三方工具都将对“日期时间”有与MySQL相同的理解。如果您使用这些自定义数据类型,想尝试在Hibernate中弄清楚是否应该使用java.sql.TimeStamp或java.util.Date对象吗?使用您的基本数据类型使第三方工具的使用变得微不足道。

这个问题与如何在数据库中存储货币价值(即1.99美元)密切相关。你应该使用Decimal,还是数据库的Money类型,或者最糟糕的是Double?所有这三个选项都很糟糕,原因与上面列出的许多相同。解决方案是使用BIGINT将货币价值存储为美分,然后在向用户显示价值时将美分转换为美元。数据库的工作是存储数据,而不是插入数据。你在数据库(尤其是Oracle)中看到的所有这些花哨的数据类型几乎没有增加什么,并开始你走向供应商锁定的道路。

引自本条:

主要区别:

TIMESTAMP用于跟踪记录的更改,并在每次记录更改时更新。DATETIME用于存储特定的静态值,不受记录中任何更改的影响。

TIMESTAMP也受不同时区相关设置的影响。DATETIME是常量。

TIMESTAMP在内部将当前时区转换为UTC进行存储,并在检索期间转换回当前时区。DATETIME无法做到这一点。

TIMESTAMP支持的范围:'1970-01-01 00:00:01′UTC至'2038-01-19 03:14:07′UTCDATETIME支持范围:'1000-01-01 00:00:00'到'9999-12-31 23:59:59'

2016+:我建议将您的MySQL时区设置为UTC并使用DATETIME:

任何最近的前端框架(Angular 1/2、React、Vue等)都可以轻松自动地将UTC日期时间转换为本地时间。

此外:

(除非您可能更改服务器的时区)


使用AngularJs的示例

// back-end: format for angular within the sql querySELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...
// font-end Output the localised time\{\{item.my_datetime | date :'medium' }}

此处提供所有本地化时间格式:https://docs.angularjs.org/api/ng/filter/date

我只是在存储UTC时使用无符号BIGINT

然后仍然可以在PHP中调整为本地时间。

DATETIMEFROM_UNIXTIME( integer_timestamp_column )一起选择。

显然应该在该列上设置索引,否则就不会有预付款。

TIMESTAMP需要4个字节,而DATETIME需要8个字节。

这里的很多答案建议在您必须表示定义良好的时间点的情况下存储为时间戳。但是,如果您按照惯例将它们全部存储在UTC中,您也可以将时间点与日期时间一起存储。

TIMESTAMP是有用的,当你有来自不同国家的游客与不同的时区.你可以很容易地转换TIMESTAMP到任何国家的时区

到目前为止没有提到的是DEFAULTCURRENT_TIMESTAMP仅适用于Timestamp,而不适用于DateTime类型字段。

这与只能使用DateTime而不能使用Timestamp的MS Access表相关。

在我的情况下,我每次都将UTC设置为所有内容的时区:系统、数据库服务器等。如果我的客户需要另一个时区,那么我会在应用程序上配置它。

我几乎总是喜欢时间戳而不是日期时间字段,因为时间戳隐式包含时区。因此,由于从不同时区的用户访问应用程序的那一刻,并且您希望他们查看本地时区的日期和时间,因此,与将数据保存在日期时间字段中相比,此字段类型使其变得非常容易。

另外,在将数据库迁移到具有另一个时区的系统的情况下,使用时间戳会更有信心。更不用说在计算两个时刻之间的差异时可能出现的问题,并且需要1小时或更短的精度。

所以,总结一下,我重视时间戳的这个优势:

  • 可在国际(多时区)应用程序上使用
  • 在时区之间轻松迁移
  • 非常容易计算差异(只需减去两个时间戳)
  • 不用担心夏天的日期/日期

出于所有这些原因,我选择可能的UTC和时间戳字段。我避免头痛;)

DATETIME、TIMESTAMP和DATE之间的比较

在此处输入图片描述

那是什么?()

  • DATETIME或TIMESTAMP值可以包含尾随小数秒部分精度高达微秒(6位)。在特别是,插入到DATETIME中的值中的任何小数部分或者TIMESTAMP列被存储而不是丢弃。这当然是可选的。

来源:

+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+|                                       TIMESTAMP                                       |                                 DATETIME                                 |+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               || Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                || TIMESTAMP supported range: ‘1970-01-01 00:00:01′ UTC to ‘2038-01-19 03:14:07′ UTC.    | DATETIME supported range: ‘1000-01-01 00:00:00′ to ‘9999-12-31 23:59:59′ || TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                || TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

timestamp是由计算机通过网络时间协议(NTP)记录的事件的当前时间。

datetime是在php配置中设置的当前时区。

在遇到许多与时区相关的问题和错误后,我停止在我的应用程序中使用datetime在大多数情况下,IMHO使用#1比#0更好

当你问什么是时间?答案是类似于'2019-02-05 21:18:30',这是未完成的,未定义的答案,因为它缺少另一个部分,在哪个时区?华盛顿?莫斯科?北京?

使用不带时区的datetime意味着您的应用程序只处理1个时区,但是时间戳为您提供了datetime的好处,以及在不同时区显示相同确切时间点的灵活性。

以下是一些会让您后悔使用datetime并希望将数据存储在时间戳中的情况。

  1. 为了您的客户的舒适度,您希望根据他们的首选时区向他们显示时间,而无需让他们做数学运算并将时间转换为有意义的时区。所有您需要的是更改时区,您的所有应用程序代码将是相同的。(实际上,您应该始终在应用程序开始时定义时区,或者在PHP应用程序的情况下定义请求处理)

    SET time_zone = '+2:00';
  2. you changed the country you stay in, and continue your work of maintaining the data while seeing it in a different timezone (without changing the actual data).

  3. you accept data from different clients around the world, each of them inserts the time in his timezone.

In short

datetime = application supports 1 timezone (for both inserting and selecting)

timestamp = application supports any timezone (for both inserting and selecting)


This answer is only for putting some highlight on the flexibility and ease of timestamps when it comes to time zones , it is not covering any other differences like the column size or range or fraction.

如果您想保证您的应用程序在2038年2月不起作用,请使用TIMESTAMP。有关支持的日期范围,请参阅您的REFMAN。

DATETIME不携带时区信息,并且将始终显示与会话有效的时区无关的相同时区,除非您显式更改了它,否则默认为服务器的时区。但是,如果我使用NOW()之类的函数而不是'2020-01-16 12:15:00'之类的文字初始化DATETIME列,那么存储的值当然将是本地化为会话时区的当前日期和时间。

相比之下,TIMESTAMP确实隐式携带时区信息:当您使用值初始化TIMESTAMP列时,该值在存储之前会转换为UTC。如果存储的值是文字,例如'2020-01-16 12:15:00',则出于转换目的,它被解释为处于会话的当前时区。相反,当显示TIMESTAMP列时,它将首先从UTC转换为会话的当前时区。

什么时候使用一个或另一个?案例研究

一个社区剧团的网站正在展示它正在售票的戏剧的几场演出。这些演出的日期和时间将出现在一个下拉列表中,希望购买演出门票的客户将从中选择一场。数据库列performance_date_and_timeDATETIME类型是有意义的。如果演出在纽约,有一个理解,即涉及一个隐含的时区(“纽约当地时间”),理想情况下,我们希望日期和时间显示为“2019年12月12日晚上8:00”,而不管会话的时区如何,并且不必费力进行任何时区转换。

另一方面,一旦2019年12月12日晚上8点的表演开始,我们可能不再想为其出售门票,因此不再在下拉列表中显示该表演。因此,我们希望能够知道'2019-12-12 20:00:00'是否发生。这将主张有一个TIMESTAMP列,将会话的时区设置为set session time_zone='America/New_York'的“America/New_York”,然后将'2019-12-12 20:00:00'存储到TIMESTAMP列中。此后,我们可以通过将该列与独立于当前会话时区的NOW()进行比较来测试性能是否已经开始。

或者,为了这两个不同的目的,有一个DATETIME和一个TIMESTAMP列可能是有意义的。或者不是。显然,任何一个都可以同时满足这两个目的。如果您只使用DATETIME列,那么您必须在与NOW()比较之前将当前时区设置为您的本地时区。如果您只使用TIMESTAMP列,您必须在显示列之前将会话时区设置为您的本地时区。

都不是。#0#1类型在通用用例中从根本上被打破。MySQL将来会改变它们。除非您有特定的理由使用其他东西,否则您应该使用#2和UNIX时间戳。

特殊情况

这里有一些具体的情况,你的选择更容易,你不需要这个答案中的分析和一般建议。

  • 仅限日期-如果你只关心日期(比如下一个农历新年的日期,2022-02-01),并且你清楚地了解该日期适用的时区(或者不在乎,就像农历新年一样),那么使用#0列类型。

  • 记录插入时间-如果您正在记录数据库中行的插入日期/时间,并且您不关心您的应用程序将在未来17年内破裂,那么继续使用TIMESTAMP,默认值为CURRENT_TIMESTAMP()

为什么TIMESTAMP坏了?

TIMESTAMP类型存储在UTC时区的磁盘上。这意味着如果您物理移动服务器,它不会中断。这很好✅。但是当前定义的时间戳将在2038❌完全停止工作。

每次INSERT INTOSELECT FROMTIMESTAMP列时,都会考虑客户端/应用程序服务器的物理位置(即时区配置)。如果您移动应用程序服务器,则日期会中断❌。

(更新2022-04-29 MySQL在8.0.28中修复了这个问题但如果您的正式生产环境是CentOS 7或许多其他版本,您的迁移路径将需要很长时间才能获得此支持。)

为什么VARCHAR坏了?

VARCHAR类型允许以ISO 8601格式明确存储非本地日期/时间/,并且它适用于2037年以后的日期。使用Zulu时间很常见,但ISO 8601允许对任何偏移进行编码。这不太有用,因为虽然MySQL日期和时间函数确实支持字符串作为输入,但如果输入使用时区偏移,结果是不正确的。

VARCHAR也使用额外的存储字节。

为什么DATETIME坏了?

ADATETIMEDATETIME存储在同一列中。除非时区被理解,否则这些都没有任何意义,并且时区不会存储在❌的任何地方。您应该将预期的时区作为注释放在列中,因为时区与数据密不可分。所以很少有人使用列注释,因此这是等待发生的错误。我从亚利桑那州继承了一台服务器,所以我总是需要将所有时间戳从亚利桑那州时间转换到另一个时间。

(更新2021-12-08多年正常运行后,我重新启动了服务器,数据库客户端(升级)重置为UTC。这意味着我的应用程序需要以不同的方式处理重置前后的日期。硬代码!)

DATETIME唯一正确的情况是完成这个句子:

你的2020年太阳新年正好从DATETIME("2020-01-01 00:00:00")开始。

DATETIME没有其他好的用途。也许你会想象特拉华州一个市政府的网络服务器。当然,这个服务器的时区和所有访问这个服务器的人都可以暗示在特拉华州,东部时区,对吗?错!在这个千年,我们都认为服务器存在于“云端”。所以认为你的服务器在任何特定的时区总是错误的,因为你的服务器总有一天会被移动。

注意:MySQL现在在DATETIME文字中排名第2(感谢@马可)。这可能会使插入DATETIME对您来说更方便,但并不能解决数据的不完整和因此无用的含义,这个致命的问题标识(“❌”)上面。

如何使用BIGINT

定义:

CREATE TEMPORARY TABLE good_times (a_time BIGINT)

插入一个特定值:

INSERT INTO good_times VALUES (UNIX_TIMESTAMP(CONVERT_TZ("2014-12-03 12:24:54", '+00:00', @@global.time_zone)));

插入一个默认值(thxBrad

ALTER TABLE good_times MODIFY a_time BIGINT DEFAULT (UNIX_TIMESTAMP());

或者,当然,这在您的应用程序中要好得多,例如:

$statement = $myDB->prepare('INSERT INTO good_times VALUES (?)');$statement->execute([$someTime->getTimestamp()]);

选择:

SELECT a_time FROM good_times;

过滤相对时间(选择过去30天内的帖子,查找注册后10分钟内购买的用户)的技术超出了此处的范围。

数据与时间戳:

TIMESTAMP用于跟踪记录的更改,并在每次记录更改时更新。

DATETIME用于存储不受记录中任何更改影响的特定和静态值。

TIMESTAMP也受不同时区相关设置的影响。DATETIME是常量。

TIMESTAMP在内部将当前时区转换为UTC进行存储,并在检索期间将其转换回当前时区。

DATETIME不能这样做。

TIMESTAMP为4字节,DATETIME为8字节。

TIMESTAMP支持的范围:'1970-01-01 00:00:01′UTC至'2038-01-19 03:14:07′UTCDATETIME支持范围:'1000-01-01 00:00:00'到'9999-12-31 23:59:59'

数据类型用于包含日期和时间部分的值。MySQL以格式检索和显示DATETIME值。支持的范围是。'YYYYYY-MM-DD hh: mm: ss''1000-01-01 00:00:00"9999-12-31 23:59:59'

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

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

URL MySQL 8.0:https://dev.mysql.com/doc/refman/8.0/en/datetime.html