Mismatch when converting Excel date numbers to Unix Timestamp using PHP - php

Hi~ I am using PHPExcel 1.7.7 to read XLSX files and present the results in web pages.
I'm trying to get the value of a cell that stores a date & time string and process it in PHP using the following code.
<?php
date_default_timezone_set('Australia/Canberra');
$value = $objPHPExcel->getActiveSheet()->getCell('A1')->getValue();
define('MIN_DATES_DIFF', 25569);
define('SEC_IN_DAY', 86400);
function excel2Timestamp($excelDate)
{
if($excelDate <= MIN_DATES_DIFF)
{
return 0;
}
return ($excelDate - MIN_DATES_DIFF) * SEC_IN_DAY;
}
echo $result = date('H:i:s d/m/Y', excel2Timestamp($value));
?>
while the original value in the cell is "00:00:00 01/07/2012", instead of giving me the correct results, the output from the above PHP code shows "10:00:00 01/07/2012".
It seems that it is caused by the time zone differences, but I have already defined the time zone at the beginning of the code. No idea what is wrong with it.
Can anyone please help me with it? Thanks in advance.

Forget your function to convert to timestamp (I was doing the same too)... PHPExcel does the convertion automatically, so try doing this:
//get the excel date value (if it's stored in the A1 cell)
$excelDate = $objPHPExcel->getActiveSheet()->getCell('A1')->getValue();
//converts from excel format to a datetime object
$date = PHPExcel_Shared_Date::ExcelToPHPObject($excelDate);
//format the date as you want.
$formatedDate = $date->format('m/d/Y');
It should work.

Related

PHPSpreadsheet: Formatting a cell for time also includes the date

I am trying to format a time cell using PHPSpreadsheet but it seems to be including the date as well when looking at the formula bar. There also seems to be some inconsistency when converting from a string, datetime object or unix timestamp.
<?php
include '../vendor/autoload.php';
use \PhpOffice\PhpSpreadsheet\Spreadsheet;
use \PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$times = [
'16:00:00',
new \DateTime('16:00:00'),
\strtotime('16:00:00'),
'2020-04-04 16:00:00',
new \DateTime('2020-02-04 16:00:00'),
\strtotime('2020-02-04 16:00:00'),
];
$format = \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_TIME1;
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
foreach ($times as $i => $time) {
$sheet->setCellValue('A' . ($i+1), \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($time));
$sheet->getStyle('A' . ($i+1))->getNumberFormat()->setFormatCode($format);
}
$writer = new Xlsx($spreadsheet);
$writer->save('test.xlsx');
From \PHPOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_TIME1: const FORMAT_DATE_TIME1 = 'h:mm AM/PM';
Is this a bug or intended functionality? Considering as const FORMAT_DATE_DATETIME = 'd/m/yy h:mm'; does include some date parameters I think there's something wrong happening.
Here's some screenshots of what happens:
But if we type in "5:00 AM" into a cell, the formula bar does not include the date:
Here is the screen that pops up from Right Click > "Format Cell":
Can someone please tell me if I'm doing something wrong, thankyou.
I figured out how to fix this problem: You need to calculate the Excel representation of the timestamp and then get only the numbers after the decimal place.
<?php
$timestamp = new \DateTime('16:00:00');
$excelTimestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($timestamp);
$excelDate = floor($excelTimestamp);
$time = $excelTimestamp - $excelDate;
From the documentation:
In Excel, dates and Times are stored as numeric values counting the number of days elapsed since 1900-01-01. For example, the date '2008-12-31' is represented as 39813. You can verify this in Microsoft Office Excel by entering that date in a cell and afterwards changing the number format to 'General' so the true numeric value is revealed. Likewise, '3:15 AM' is represented as 0.135417.
I hope this helps anybody else stuck with this problem.
You must set the right number format see for more information the official sample documentation.
The number format that you set is 'h:mm AM/PM' means that there is no date included only the time.
When you change to 5 PM you overwrite the content and the number format will used.
If you will have a date you should try to set 'd/m/yy h:mm AM/PM'.

How to change excel cell date fromat using PHP

I want to upload data from csv file and my database only accept yyy-mm-dd date format but sometimes users will enter data as dd/mm/yyy date format so I am tried to do following method using Keboola\Csv
if($header[$c]=='date' && $row[$c]!='')
{
$date_text=['--na','--N/'];
$sexe_text=str_replace($date_text,'N/A',$row[$c]);
if(in_array(array('--na','--N/'),$row))
{
$newRow[$c]=$sexe_text;
}
else
{
$date_array=explode('/', trim($row[$c]));
$date=trim($date_array[0]);
$month=trim($date_array[1]);
$year=trim($date_array[2]);
$date_time=$year.'-'.$month.'-'.$date;
$newRow[$c]=$date_time;
}
}
But it will revert again if that cell format in dd/mm/yyy so Now I want to change that cell format into date YYY-MM-DD how can I do it using PHP
You can direct convert it using date() function.
$exceldate = trim($row[$c]);
$date = date('Y-m-d',strtotime($exceldate));
echo $date;
// 2019-08-09
PHP has already predefined date() to convert dates in any format
Simply replace your code with the code given below
if($header[$c]=='date' && $row[$c]!='')
{
$row[$c] = date('Y-m-d', strtotime($row[$c]));
}
else
{
# if $row[$c] is null, do whatever you want.
}
The PHP date() accepts date in any format, wheather it is separated by forward slashes or hyphens.
To learn more you can see this documentaion
for date() : https://www.php.net/manual/en/function.date.php
and for strtotime() : https://www.php.net/manual/en/function.strtotime.php

Read date value from import Excel in PHP

I've problem with read date value from import value (Excel) to mysql database. i've code as below :
$dataexcel[$i-3]['date_edit'] = date('m/d/Y', strtotime(trim($data['cells'][$i][25])));
i tried use strtotimeto define value from excel, but i've problem to save it into database, if my value in excel with excel date format is 1/1/2018 (it read as 1 Jan 2018, English time format), after i used my code above, it saved become 1970-01-01 it means 1 Jan 1970.
in another example,
i tried another input with date 2/1/2018, it saved into database as 2018-02-02.
from my samples above, in first there missmatch problem with year, then and in the 2nd sample missmatch problem come from date,
so how to declare date to solve my problem, if i want to save date format with simple way?
if there any advice , please, thanks...
From your comment answer, you can modification some code like below :
$date = str_replace("/", ".", $data['cells'][$i][25]);
$dates = date("Y-m-j", strtotime($date));
$dataexcel[$i-3]['date_edit'] = $dates;
$date still pick up from value without used strotime, so date format didn't read correctly...
You can convert the excel date to mysql date like below I did.
//Your input date
$input_date = $sheet->getCellByColumnAndRow(1,$i)->getValue();
$excel_date = $input_date; //here is that excel value 41621 or 41631
//Convert excel date to mysql db date
$unix_date = ($excel_date - 25569) * 86400;
$excel_date = 25569 + ($unix_date / 86400);
$unix_date = ($excel_date - 25569) * 86400;
//echo gmdate("Y-m-d", $unix_date);
//Insert below to sql
$added_date = gmdate("Y-m-d", $unix_date);
A simple function will do this thing
$date = str_replace("/", ".", $data['cells'][$i][25]);// replace the / with .
$date = date("Y-m-d", strtotime($date));
$dataexcel[$i-3]['date_edit'] = $date;
And in the database the default date format is YYYY-MM-DD , so it save correctly to the db
keep it simple. use a defined dateformat when reading the file (the dateformat can be provided as a parameter in case it needs to be adjustable). then, read the date in the following way instead of just using strtotime (taken from php.net's example):
$date = DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
relevant example to your code, using the previous $date var:
$dataexcel[$i-3]['date_edit'] = $date->format("y-M-Y");
more info - http://php.net/manual/en/datetime.createfromformat.php

Reading date from uploaded Excel file

I am uploading an Excel file through PHP Excel. The column C has dates in format mm/dd/yyy.
When I echo the date for example '10/3/2016' it reads it as 42646. The format set for the column is short Date.
How can I read it as the normal date instead of 42646.
here is the model
function fi_upload($file_name){
$file = './uploads/'.$file_name;
$this->load->library('excel');
$objPHPExcel = PHPExcel_IOFactory::load($file);
$cell_collection = $objPHPExcel->getActiveSheet()->getCellCollection();
foreach ($cell_collection as $cell) {
$column = $objPHPExcel->getActiveSheet()->getCell($cell)->getColumn();
$row = $objPHPExcel->getActiveSheet()->getCell($cell)->getRow();
$data_value = $objPHPExcel->getActiveSheet()->getCell($cell)->getValue();
if ($row == 1) {
$header[$row][$column] = $data_value;
} else {
$arr_data[$row][$column] = $data_value;
}
}
$data['header'] = $header;
$data['values'] = $arr_data;
$datecell = $objPHPExcel->getActiveSheet()->getCell('P2');
if(PHPExcel_Shared_Date::isDateTime($datecell)) {
$InvDate = date($format="Y-m-d", PHPExcel_Shared_Date::ExcelToPHP($datecell));
}
echo $InvDate;
exit();
foreach ($arr_data as $q){
echo $q['C']; // column of date, date is echoed as 42646
exit(); //here i exit to display the date
}
I have to later insert it in the database as well in the yyyy/mm/dd format (which I can do if it is read properly)
Thanks.
UPDATE:
So apparently it was an Excel file issue, not php. Converting the cell values through TEXT() was the solution as suggested by #Hallur.
UPDATE 2.0:
I am trying to do it via PHPEXCEL method but I get the following two issues.
: Object of class PHPExcel_Cell could not be converted to int
Echoes date as 2036-02-07 where as the date in cell is 10/4/2016
42646 is an MS Excel serialized timestamp value, the number of days since 1st January 1900 (or 1st January 1904, depending on whether the spreadsheet is using the Windows or Mac calendar)
PHPExcel provides a variety of functions to convert values between MS Excel serialized timestamps and Unix timestamps or PHP DateTime objects (or vice versa), all of which can be found in the PHPExcel_Shared_Date class, e.g.
ExcelToPHP() to convert an MS Excel serialized timestamp to a unix timestamp
ExcelToPHPObject() to convert an MS Excel serialized timestamp to a PHP DateTime object
Alternatively, using the getFormattedValue() method instead of getValue() will return a formatted date/time string value instead of the serialized tiemstamp
$field1= $objWorksheet->getCellByColumnAndRow(0,$i)->getFormattedValue(); //Excel Column 3
$date = PHPExcel_Shared_Date::ExcelToPHP($field1); //unix
echo $field1= gmdate("Y-m-d", $date); //date
Already wrote answer this link
The answer to this question is here:
Excel weird behaviour with dates => text
The number 42646, is the amount of days since january 1st year 1900.
To convert the excel base date to unix time ( time() ), you must calculate the difference between unix start to excel base time start. (unix start: d-m-Y H:i:s -> 01-01-1970 01:00:00) (excel start: d-m-Y -> 1-1-1900)
First to get the difference, which is approximately 70 years and 1 hour (+ 1 extra day because excel date 1-1-1900 = 1, not 0.)
70 years, 1 day, 1 hour = 70 years + 25 hours. (to make up for leap years, we have to say 365.25 instead of 365 days in a year)
(70*365.25*24*60*60)+(25*60*60)
Now, we need to convert the excel date value to seconds as well: 42646*24*60*60 (~ 116 years)
We need to subtract them from each other to get the unix time, and since the excel date is higher than the 70 years, we put that first.
to echo out the day:
echo date("d-m-Y", (42646*24*60*60) - ((70*365.25*24*60*60)+(25*60*60)));
EDIT: I just realized that extra hour is because of my timezone.. CET, not UTC.

Error Import Excel Date PHP

I have a problem trying to upload an excel to my database through PHP.
The format I have in the excel is dd/mm/yyyy and my sql needs yyyy/mm/dd
$_DATOS_EXCEL[$i]['ship_day']= $objPHPExcel->getActiveSheet()- >getCell($headings['Ship Date'].$i)->getFormattedValue();
I tried
getFormattedValue('YYYY/MM/DD');
but doesnt work
I really appreciate if you can help me out with this.
If your cell value really is an Excel serialized date/time value, and you know which cells contain these dates, then you can convert it directly to a PHP DateTime object
$dto = PHPExcel_Shared_Date::ExcelToPHPObject(
$objPHPExcel->getActiveSheet()
->getCell($headings['Ship Date'].$i)
->getValue()
);
$_DATOS_EXCEL[$i]['ship_day'] = $dto->format('Y/m/d');
or to a Unix Timestamp
$unixTimestamp = PHPExcel_Shared_Date::ExcelToPHP(
$objPHPExcel->getActiveSheet()
->getCell($headings['Ship Date'].$i)
->getValue()
);
$_DATOS_EXCEL[$i]['ship_day'] = date('Y/m/d', $unixTimestamp);
Add three line after
"$_DATOS_EXCEL[$i]['ship_day']= $objPHPExcel->getActiveSheet()- >getCell($headings['Ship Date'].$i)->getFormattedValue();"
this line......
$rearrange=$_DATOS_EXCEL[$i]['ship_day'];
$explode = explode("/",$rearrange);
$_DATOS_EXCEL[$i]['ship_day']= $explode[2]."/".$explode[1]."/".$explode[0];

Categories