使用 PHP Excel 进行 Excel 日期转换

27

我正在从Excel读取日期,其格式为12/5/2012,即日/月/年。我正在使用 PHP EXCEL 进行读取。

   PHPExcel_Style_NumberFormat::toFormattedString($value['A'],'YYYY-MM-DD' );

它能够完美地将上述日期“12/5/2012”转换成“2012-12-05”。

现在的问题是,如果日期是“18/5/2012”,或者说如果我设置的日期大于12,它会给我一个这样的日期格式“18/5/2012”。我尝试了这个方法。

      $temp  = strtotime(  PHPExcel_Style_NumberFormat::toFormattedString($value['A'],'YYYY-MM-DD' );
      $actualdate = date('Y-m-d',$temp) ;

这也可以正确转换日期 '12/5/2012',但在这种情况下,即 18/5/2012,它的输出为1970-01-01。


你提供的示例仍无法正确转换 - 2012年12月5日从英国格式转换为ISO格式应返回2012-05-12。 - SeanC
是的,你说得对,我没有注意到那个......为了以这种格式 2012-05-12 呈现,我必须将字符串格式设置为 YYYY-DD-MM。 - Abdul basit
1
这个值是Excel的日期时间戳还是字符串?如果是前者,为什么不使用PHPExcel_Shared_Date转换方法,例如ExcelToPHP()或ExcelToPHPObject()?如果是后者,则不应使用toFormattedString()。 - Mark Baker
6个回答

101
请使用下面的公式将Excel日期转换为Unix日期,然后您可以使用"gmdate"在PHP中获取实际日期:
UNIX_DATE = (EXCEL_DATE - 25569) * 86400

要将Unix日期转换为Excel日期,请使用以下公式:

EXCEL_DATE = 25569 + (UNIX_DATE / 86400)

将此公式放入变量后,您可以使用以下示例在PHP中获取实际日期:

$UNIX_DATE = ($EXCEL_DATE - 25569) * 86400;
echo gmdate("d-m-Y H:i:s", $UNIX_DATE);

3
好的。25569是Excel中用于日期计算的基准日期,它对应于1900年1月1日。而86400代表一天中的秒数,用于将日期值转换为UNIX时间戳格式。 - idok
11
我可以。86400是一天的秒数= 24 * 60 * 60。25569是从1900年1月1日到1970年1月1日的天数。 Excel基准日期为1900年1月1日,UNIX为1970年1月1日。 UNIX日期值以从1970年1月1日(1969年12月31日午夜)开始的秒数表示。因此,要从Excel转换,必须减去天数,然后转换为秒数。 - TJChambers
1
我们可以使用内置函数toFormattedString吗?echo PHPExcel_Style_NumberFormat::toFormattedString(42033, 'YYYY-MM-DD'); 将输出2015-01-29。 - Hắc Huyền Minh
2
哦,我真的需要这个,无法搞清楚Excel给我的那个数字是什么鬼。 - Someone
这个答案对于所有的Excel日期来说是不完整的,因为它们可以在距离1900年1月1日的天数后带有一个逗号和一小部分天数。 - QuidamAzerty
1
使用UNIX_DATE = round((EXCEL_DATE - 25569) * 86400)来纠正秒数。 - David Vielhuber

30

使用PHPExcel时,您可以使用内置函数:

$excelDate = $cell->getValue(); // gives you a number like 44444, which is days since 1900
$stringDate = \PHPExcel_Style_NumberFormat::toFormattedString($excelDate, 'YYYY-MM-DD');

2

An easy way...

<?php
    $date = date_create('30-12-1899');

    date_add($date, date_interval_create_from_date_string("{$value['A']} days"));
    echo date_format($date, 'Y-m-d');

0

看起来您的变量是一个字符串,或者期望一个美国格式的日期。
使用 'DateTime::createFromFormat' 将日期转换为实际日期格式。

$date = DateTime::createFromFormat('d/m/y', $value['A']);
echo $date->format('Y-m-d');

1
致命错误:在非对象上调用成员函数format(),它给我返回了这个错误。我正在使用PHP 5.4.3。 - Abdul basit
1
如果回显无法正常工作,那么这只是一个小问题 - PHPExcel_Style_NumberFormat::toFormattedString(DateTime::createFromFormat('d/m/y', $value['A']),'YYYY-MM-DD' ); - SeanC

-1

考虑到 1664193600000 = 2022年9月26日 12:00:00,从 Excel 到 Unix 的答案是:

UNIX_DATE = (EXCEL_DATE - 25569) * 86400000

从UNIX到Excel

EXCEL_DATE = 25569 + (UNIX_DATE / 86400000)

PHP中的UNIX_DATE以毫秒为单位给出。

86400000ms对应于24小时/天*3600秒/小时*1000毫秒/秒

25569是从1900年1月1日1970年1月1日的天数。


-3
如果您正在使用Python,我通过从xlrd库中添加xldate类来解决了这个问题。在这里,我向您展示代码(这是在Odoo 10模块中的):
from xlrd import open_workbook, xldate
wb = open_workbook(file_contents=excel_file)
data_sheets = []

        # Parse all data from Excel file
        for s in wb.sheets():
            data_rows = []
            headers = []
            for row_key, row in enumerate(range(s.nrows)):
                if row_key != 0:
                    data_row = {}
                    for index, col in enumerate(range(s.ncols)):
                        value = s.cell(row, col).value
                        key = headers[int(index)]
                        if key == 'Date' and (isinstance(value, float) or isinstance(value, int)):
                            value = xldate.xldate_as_datetime(value, wb.datemode)
                            data_row[key] = value
                        else:
                            data_row[key] = value

                    data_rows.append(data_row)
                else:
                    for index, col in enumerate(range(s.ncols)):
                        value = (s.cell(row, col).value)
                        headers.append(value)
            data_sheets.append(data_rows)

value = xldate.xldate_as_datetime(value, wb.datemode) 将返回带有正确值的日期时间对象


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接