RDS MySQL中TIMESTAMP字段写入2038年后时间报错

问题描述

当向MySQL表中插入数据时,若某字段类型为TIMESTAMP,且写入的时间值超过其最大有效范围(如2039-10-12 12:12:12),系统将返回如下报错:

ERROR 1292 (22007): Incorrect datetime value: '2039-10-12 12:12:12' for column 'c1' at row 1

image

问题原因

MySQL支持多种日期时间类型,每种类型的存储方式和取值范围不同。本问题源于TIMESTAMP类型的固有限制,TIMESTAMP的上限为UTC时间2038-01-19 03:14:07,对应Unix时间戳2147483647。一旦超出此范围,即触发报错。各时间类型取值范围对比如下:

数据类型

取值范围

存储空间

说明

TIMESTAMP

'1970-01-01 00:00:01'UTC~'2038-01-19 03:14:07'UTC

4 字节

基于Unix时间戳,受32位整数限制。

DATETIME

'1000-01-01 00:00:00'~'9999-12-31 23:59:59'

8 字节

不依赖时区,范围广,推荐用于长期时间存储。

DATE

'1000-01-01'~'9999-12-31'

3 字节

仅存储日期部分(年-月-日)。

TIMESTAMP类型在存储时会自动将输入的时间值从当前会话时区转换为UTC时间进行保存,并在校验阶段以UTC范围为准。因此,实际可写入的“本地时间”会因时区不同而略有差异。例如:

  • UTC最大值:2038-01-19 03:14:07

  • 对应中国标准时间(CST,UTC+8):2038-01-19 11:14:07

因此在东八区最多可写入至2038-01-19 11:14:07 的时间值。但一旦超过此边界(如2039-01-01),无论时区如何,均会触发错误。更多详情,请参见TIMESTAMP类型说明

解决方案

  • 建议结合业务逻辑,避免使用超出数值范围的情况。

  • 若用户业务需要使用超出数值范围的数值,建议评估使用其它数据类型,比如使用DATETIMEVARCHAR类型。

  • (不推荐使用)若只为避免报错,业务侧接受全0的数据,如0000-00-00 00:00:00,可以直接调整参数,关闭SQL_MODE中的严禁策略STRICT_TRANS_TABLES,请知悉STRICT_TRANS_TABLES的开启影响后再操作。

适用于

  • RDS MySQL

  • PolarDB MySQL