Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP&;mySQL:2038年错误:是什么?如何解决?_Php_Mysql_Year2038 - Fatal编程技术网

PHP&;mySQL:2038年错误:是什么?如何解决?

PHP&;mySQL:2038年错误:是什么?如何解决?,php,mysql,year2038,Php,Mysql,Year2038,我想用时间戳来存储日期+时间,但我读到它有2038年的限制。我宁愿把问题分成几个小部分,以便新手也能容易地理解,而不是成堆地问我的问题。因此,我的问题是: 2038年的问题到底是什么 为什么会发生,发生时会发生什么 我们如何解决它 是否有任何可能的替代方案来使用它,而这些替代方案不会造成类似的问题 我们可以对使用时间戳的现有应用程序做些什么来避免所谓的问题,当它真正发生时 提前感谢。在使用UNIX时间戳存储日期时,实际上使用的是32位整数,用于记录自1970-01-01以来的秒数;看 该32位数

我想用时间戳来存储日期+时间,但我读到它有2038年的限制。我宁愿把问题分成几个小部分,以便新手也能容易地理解,而不是成堆地问我的问题。因此,我的问题是:

  • 2038年的问题到底是什么
  • 为什么会发生,发生时会发生什么
  • 我们如何解决它
  • 是否有任何可能的替代方案来使用它,而这些替代方案不会造成类似的问题
  • 我们可以对使用时间戳的现有应用程序做些什么来避免所谓的问题,当它真正发生时

  • 提前感谢。

    在使用UNIX时间戳存储日期时,实际上使用的是32位整数,用于记录自1970-01-01以来的秒数;看

    该32位数字将在2038年溢出。这就是2038年的问题


    为了解决这个问题,您不能使用32位UNIX时间戳来存储日期——这意味着,在使用MySQL时,您不应该使用
    时间戳
    ,而应该使用
    日期时间
    (请参阅):

    DATETIME
    类型用于 需要同时包含日期和时间的值 时间信息。支持的范围 是
    '1000-01-01 00:00:00'
    '9999-12-3123:59:59'

    时间戳
    数据类型有一个范围 世界时1970-01-01 00:00:01至
    '2038-01-19 03:14:07'
    UTC


    为了避免/修复该问题,您可以对应用程序做的(可能)最好的事情是不要对必须包含日期不在1970和2038之间的列使用
    时间戳
    ,而是使用
    日期时间

    不过,有一点需要注意:在2038年之前,你的应用程序很可能会被重新编写好几次(从统计上讲),因此,如果你不必处理未来的日期,您不必在当前版本的应用程序中处理该问题…

    我已将此标记为社区wiki,因此您可以随意编辑

    2038年的问题到底是什么? “2038年的问题(也被称为Unix千年虫,与Y2K问题类似的Y2K38)可能导致某些计算机软件在2038年之前或之后出现故障。该问题影响所有将系统时间存储为有符号32位整数的软件和系统,并将该数字解释为自1970年1月1日UTC 00:00:00以来的秒数。”


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


    我们如何解决它?
    • 使用长数据类型(64位就足够了)
    • 对于MySQL(或MariaDB),如果不需要时间信息,请考虑使用<代码>日期<代码>列类型。如果需要更高的精度,请使用
      DATETIME
      而不是
      TIMESTAMP
      。请注意,
      DATETIME
      列不存储有关时区的信息,因此应用程序必须知道使用了哪个时区
    • 等待MySQL开发人员修复十多年前的报告

    是否有任何可能的替代方案来使用它,而这些替代方案不会造成类似的问题? 尽可能使用大类型在数据库中存储日期:64位就足够了——GNU C和POSIX/SuS中的长类型,或PHP或BCmath扩展中的
    sprintf(“%u”…)


    即使我们还没有到2038年,还有哪些潜在的破坏性用例? 所以MySQL的范围是1000-9999,但时间戳的范围只有1970-2038。如果您的系统存储生日、未来的远期日期(例如,30年期抵押贷款)或类似信息,则您已经将遇到此错误。同样,如果这将是一个问题,不要使用时间戳


    我们可以对使用时间戳的现有应用程序做些什么来避免所谓的问题,当它真正发生时? 2038年,很少有PHP应用程序仍然存在,尽管很难预见web还不是一个遗留平台

    下面是一个更改数据库表列以将
    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`
    

    资源


      • 在谷歌上快速搜索就可以做到:

      • 2038年的问题(也被称为Unix千年虫,与Y2K问题类似的Y2K38)可能会导致某些计算机软件在2038年之前或之后出现故障
      • 此问题影响所有将系统时间存储为有符号32位整数的软件和系统,并将此数字解释为自1970年1月1日UTC 00:00:00以来的秒数。可以用这种方式表示的最晚时间是2038年1月19日星期二UTC 03:14:07。超过这一时刻的时间将“环绕”,并在内部存储为负数,这些系统将其解释为1901年的日期,而不是2038年的日期
      • 对于现有的CPU/OS组合、现有的文件系统或现有的二进制数据格式,这个问题没有简单的解决方法
      • 有大部分的细节

        总之:

        1) +2)问题是许多系统将日期信息存储为32位带符号整数,等于自1970年1月1日以来的秒数。可以这样存储的最新日期是2038年1月19日星期二03:14:07 UTC。发生这种情况时,int将“环绕”并存储为负数,该负数将被解释为1901年的日期。接下来会发生什么,因系统而异
        $qry = "select DATEADD(month, 1, :date) next_date ";
        $rs_tmp = $pdo->prepare($qry);
        $rs_tmp->bindValue(":date", '2038/01/15');
        $rs_tmp->execute();
        $row_tmp = $rs_tmp->fetch(PDO::FETCH_ASSOC);
        
        echo $row_tmp['next_date'];