本文介绍了PHP &mySQL:2038 年错误:它是什么?如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 TIMESTAMP 来存储日期+时间,但我读到它有 2038 年的限制.与其大量问我的问题,我更喜欢把它分解成小部分,这样新手用户也很容易理解.所以我的问题:

I was thinking of using TIMESTAMP to store the date+time, but I read that there is a limitation of year 2038 on it. Instead of asking my question in bulk, I preferred to break it up into small parts so that it is easy for novice users to understand as well. So my question(s):

  1. 2038 年的问题究竟是什么?
  2. 为什么会发生以及发生时会发生什么?
  3. 我们如何解决?
  4. 是否有任何可能的替代方法来使用它,并且不会造成类似的问题?
  5. 当所谓的问题真正发生时,我们可以对使用 TIMESTAMP 的现有应用程序做些什么来避免所谓的问题?

提前致谢.

推荐答案

我已将此标记为社区 Wiki,因此您可以在闲暇时随意编辑.

2038 年问题(也称为 Unix Millennium Bug,Y2K38 类比于 Y2K 问题)可能会导致某些计算机软件在 2038 年之前或之后出现故障.该问题影响所有将系统时间存储为一个有符号的 32 位整数,并将这个数字解释为自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数."

"The year 2038 problem (also known as Unix Millennium Bug, Y2K38 by analogy to the Y2K problem) may cause some computer software to fail before or in the year 2038. The problem affects all software and systems that store system time as a signed 32-bit integer, and interpret this number as the number of seconds since 00:00:00 UTC on January 1, 1970."

超过 2038 年 1 月 19 日星期二 03:14:07 UTC 的时间将环绕"并在内部存储为负数,这些系统将其解释为 12 月 13 日的时间,1901 而不是 2038.这是因为自 UNIX 时代(1970 年 1 月 1 日 00:00:00 GMT)以来的秒数将超过计算机的 32 位有符号整数的最大值.

Times beyond 03:14:07 UTC on Tuesday, 19 January 2038 will 'wrap around' and be stored internally as a negative number, which these systems will interpret as a time in December 13, 1901 rather than in 2038. This is due to the fact that the number of seconds since the UNIX epoch (January 1 1970 00:00:00 GMT) will have exceeded a computer's maximum value for a 32-bit signed integer.

  • 使用长数据类型(64 位就足够了)
  • 对于 MySQL(或 MariaDB),如果您不需要时间信息,请考虑使用 DATE 列类型.如果您需要更高的准确性,请使用 DATETIME 而不是 TIMESTAMP.请注意 DATETIME 列不存储有关时区的信息,因此您的应用程序必须知道使用的是哪个时区.
  • 维基百科中描述的其他可能的解决方案
  • 等待 MySQL 开发人员修复十多年前报告的这个错误.
  • Use long data types (64 bits is sufficient)
  • For MySQL (or MariaDB), if you don't need the time information consider using the DATE column type. If you need higher accuracy, use DATETIME rather than TIMESTAMP. Beware that DATETIME columns do not store information about the timezone, so your application will have to know which timezone was used.
  • Other Possible solutions described on Wikipedia
  • Wait for MySQL devs to fix this bug reported over a decade ago.

尽量使用大类型在数据库中存储日期:64 位就足够了 - GNU C 和 POSIX/SuS 中的 long long 类型,或 sprintf('%u'...) 在 PHP 或 BCmath 扩展中.

Try wherever possible to use large types for storing dates in databases: 64-bits is sufficient - a long long type in GNU C and POSIX/SuS, or sprintf('%u'...) in PHP or the BCmath extension.

所以 MySQL DATETIME 的范围是 1000-9999,但 TIMESTAMP 只有 1970-2038 的范围.如果您的系统存储了出生日期、未来的远期日期(例如 30 年抵押贷款)或类似信息,您就会遇到这个错误.同样,如果这会成为问题,请不要使用 TIMESTAMP.

So a MySQL DATETIME has a range of 1000-9999, but TIMESTAMP only has a range of 1970-2038. If your system stores birthdates, future forward dates (e.g. 30 year mortgages), or similar, you're already going to run into this bug. Again, don't use TIMESTAMP if this is going to be a problem.

很少有 PHP 应用程序会在 2038 年仍然存在,尽管很难预见,因为网络还不是一个遗留平台.

Few PHP applications will still be around in 2038, though it's hard to foresee as the web hardly a legacy platform yet.

这是一个改变数据库表列以将TIMESTAMP 转换为DATETIME 的过程.它从创建一个临时列开始:

Here is a process for altering a database table column to convert TIMESTAMP to DATETIME. It starts with creating a temporary column:

# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;

# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;

# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);

# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`

资源

这篇关于PHP &mySQL:2038 年错误:它是什么?如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 12:49