【问题标题】:PHPExcel gets wrong timezone even after setting date_default_timezone_set即使在设置 date_default_timezone_set 之后,PHPExcel 也会出现错误的时区
【发布时间】:2012-06-04 20:33:59
【问题描述】:

我在我的一个项目中使用http://phpexcel.codeplex.com,但遇到了问题。 我想在一个单元格中写入 time() 值,我正在这样做:

function writeTimeLine($objActiveSheet, &$lineNumber, $timeStart, $timeEnd, $duration, $category, $client, $date, $comment)
{
    $objActiveSheet->setCellValue('A'.$lineNumber, PHPExcel_Shared_Date::PHPToExcel( $timeStart ));
    $objActiveSheet->getStyle('A'.$lineNumber)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
}

$objActiveSheet 指的是 $objPHPExcel->getActiveSheet()

Excel 中的结果是:

20:27:39

当我在电脑上进行真实测试时,时间是 16:27:39

所以这是时区的问题(我住在东美洲,即-4)。 但是,在使用

设置默认时区后,我将包含 PHPExcel 文件
date_default_timezone_set('America/New_York');

即使有 time() 的回声,我也确实看到了正确的时间 (16:27:39)。

这是 PHPExcel 的错误还是我在这里做错了什么?

感谢您的帮助。

【问题讨论】:

    标签: php timezone phpexcel


    【解决方案1】:

    您最好添加时间差,而不是更改 PHPExcel 库:

    $timeStart + date('Z', $timeStart)

    例如这样:

    date_default_timezone_set('America/New_York');
    function writeTimeLine($objActiveSheet, &$lineNumber, $timeStart, $timeEnd, $duration, $category, $client, $date, $comment)
    {
        $objActiveSheet->setCellValue('A'.$lineNumber, PHPExcel_Shared_Date::PHPToExcel( $timeStart + date('Z', $timeStart) ));
        $objActiveSheet->getStyle('A'.$lineNumber)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);
    }

    【讨论】:

      【解决方案2】:

      刚刚发现问题:PHPExcel在里面转换为UTC时间: PHPExcel/Shared/Date.php

      函数PHPToExcel将时区临时更改为UTC,然后返回默认时区。

      解决方案很简单,但需要更改该文件。 只需复制粘贴 PHPToExcel 函数,将其命名为 PHPToExcelWithoutUTC(或您想要的任何名称)并注释以下行:

      //$saveTimeZone = date_default_timezone_get();
      //date_default_timezone_set('UTC');
      
      //date_default_timezone_set($saveTimeZone);
      

      而且它有效。

      编辑:似乎默认情况下始终使用 UTC 时间。我不会删除这个帖子,因为它可能对那些想要用户时区的人有用。

      【讨论】:

      • 它使用 UTC,因为这是一个全局常量...如果我们将默认时区保留为用户的时区,我们会遇到很多问题,因此我们假设传递给 PHPExcel 的所有日期/时间值应该是通用时间,如果不是,我们将它们转换为 UTC。
      • Excel 不转换它们,所以没用? excel 文档是为最终用户准备的,无法自行设置正确的时区,它需要 VBA 脚本或单元格之间的某种计算,所以如果我只想使用一个单元格一次,我想要它在没有任何脚本的情况下拥有它(因为它会在每次加载文件时询问我是否要在文件上启用脚本并默认阻止脚本执行):似乎我不能(除了这里给出的解决方案)。
      • 当感觉像是纯粹的负面批评时,我觉得事情很糟糕,而且感觉最近有很多这样的事情:人们说他们会设计或写得更好,但大多数人除外永远不要采取下一步并尝试编写自己的 Excel 阅读器/编写器,甚至不建议他们如何更好地编写它(这可以被视为积极的批评)。我知道 PHPExcel 有很多缺陷,当我意识到它们时,我会尝试清除它们;但有几天我觉得我不想再成为某人的 24x7x365 支持热线
      • @Janis - 您查看过 ExcelToPHP() 和 PHPToExcel() 方法的代码或 API 文档吗?他们已经有一个可选的时区参数。这是在最初发布后的一年中添加的
      • @MarkBaker ExceltoPHP 使用 adjustToTimezone 和 timezone 参数。但 PHPtoExcel 没有。这是一个已知的错误吗?
      【解决方案3】:

      授予相当陈旧,但想提供另一种解决方案。

      如果您不想编辑库源文件,因为PHPExcel_Shared_Date::PHPToExcel (1.7.8+) 接受整数时间戳或 DateTime 对象,您可以轻松地将整数时间戳转换为 DateTime 对象。

      然后 PHPToExcel 将在调用 $dateValue->format() 时使用您的 DateTime 对象的时区。

      DateTime 时区仅根据构造/修改计算,而不是根据格式计算。

      PHP 5

      $timeStart = new DateTime(date("c", $timeStart));
      PHPExcel_Shared_Date::PHPToExcel($timeStart);
      

      PHP 5 >= 5.3

      $date = new DateTime();
      PHPExcel_Shared_Date::PHPToExcel($date->setTimestamp($timeStart));
      

      注意

      在使用'@' . $timestamp 时,DateTime 构造使用 UTC 时区。

      setTimestamp 使用环境当前时区。

      但是 setTimestamp 直到 5.3 才可用

      在开发统包解决方案时,通常最好的做法是尽量避免发生任何改变或试图确定部署环境的任何事情。 我经常在其他应用程序中修复的一个很好的例子是date('Y-m-d', PHP_INT_MAX);。这在 32 位系统上可以正常工作,但不能在 64 位系统上运行(Windows 除外)。在不同环境之间产生意想不到的结果。

      【讨论】:

        【解决方案4】:

        您可以查看源代码,

        ExcelToPHP() 和 PHPToExcel()

        https://github.com/PHPOffice/PHPExcel/blob/1.8/Classes/PHPExcel/Shared/Date.php#L115

        还提供参数,以便您可以将时区从 UTC 转换为您的时区

            /**
         *    Convert a date from Excel to PHP
         *
         *    @param        integer        $dateValue            Excel date/time value
         *    @param        boolean        $adjustToTimezone    Flag indicating whether $dateValue should be treated as
         *                                                    a UST timestamp, or adjusted to UST
         *    @param        string         $timezone            The timezone for finding the adjustment from UST
         *    @return       integer        PHP serialized date/time
         */
        public static function ExcelToPHP($dateValue = 0, $adjustToTimezone = false, $timezone = null)
        

        【讨论】:

          猜你喜欢
          • 2020-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 2017-03-11
          • 1970-01-01
          • 2021-02-04
          • 2016-03-25
          相关资源
          最近更新 更多