我当时在考虑使用TIMESTAMP来存储日期和时间,但是我读到它有2038年的限制。我不想将问题大量散发,而是将其分解成小部分,以便新手用户也易于理解。所以我的问题是:

  • 2038年到底是什么问题?
  • 为什么会发生?发生时会发生什么?
  • 我们该如何解决?
  • 是否有使用它的可能替代方法,而不会引起类似的问题?
  • 如果发生真正的问题,我们该如何对使用TIMESTAMP的现有应用程序进行处理,以避免所谓的问题?

  • 提前致谢。

    最佳答案

    我已将其标记为社区Wiki,因此随时可以编辑。

    2038年到底是什么问题?

    “2038年的问题(也称为Unix Millennium Bug,类似于Y2K问题的Y2K38)可能会导致某些计算机软件在2038年之前或之前发生故障。该问题影响将系统时间存储为带符号的32的所有软件和系统。位整数,并将其解释为自1970年1月1日00:00:00 UTC以来的秒数。”

    为什么会发生?发生时会发生什么?

    03:14:07 UTC之后的时间2038年1月19日世界标准时间将“环绕”并在内部存储为负数,这些系统将其解释为1901年12月13日而不是2038年。由于以下事实:自UNIX纪元(1970年1月1日00:00:00 GMT)以来的秒数已经超过了32位带符号整数的计算机最大值。

    我们该如何解决?

  • 使用长数据类型(64位就足够了)
  • 对于MySQL(或MariaDB),如果不需要时间信息,请考虑使用DATE列类型。如果需要更高的精度,请使用DATETIME而不是TIMESTAMP。注意DATETIME列不存储有关时区的信息,因此您的应用程序将必须知道使用了哪个时区。
  • Other Possible solutions described on Wikipedia
  • 等待MySQL开发人员修复十年前报告的this bug


  • 是否有使用它的其他可能的选择,而不会引起类似的问题?

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

    即使我们还没有到2038年,仍然有哪些潜在的突破性用例?

    因此,MySQL DATETIME的范围为1000-9999,而TIMESTAMP的范围仅为1970-2038。如果您的系统存储了出生日期,将来的远期日期(例如30年的抵押贷款)或类似的日期,那么您已经遇到了这个错误。同样,如果这将成为问题,请不要使用TIMESTAMP。

    当使用TIMESTAMP的现有应用程序真正发生时,我们该怎么办?

    尽管很难预见到Web仍不是传统平台,但2038年仍将出现很少的PHP应用程序。

    这是更改数据库表列以将TIMESTAMP转换为DATETIME的过程。首先创建一个临时列:
    # 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`
    

    资源
  • Year 2038 Problem (Wikipedia)
  • The Internet Will End in 30 Years
  • 关于php - PHP&mySQL : Year 2038 Bug: What is it?如何解决?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2012589/

    10-10 07:38