Phpexcel getting wrong date - php

I am using phpexcel to import excel document to website. I have problem with getting Date format.
Date format is dd.mm.Y but after getting cellValue I get samo random numbers ( float(42391) )
This is my code:
$datum = $objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue();
this shoud get date?
$file_name = clean_uri($_FILES['excel']['name']);
$file_name = 'povijest_'.$file_name;
$folder_s = 'upload_data/excel';
move_uploaded_file($_FILES['excel']['tmp_name'], '../'.$folder_s.'/'.$file_name);
$objPHPExcel = PHPExcel_IOFactory::load('../'.$folder_s.'/'.$file_name);
$allDataInSheet = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);
$highestColumm = $objPHPExcel->getActiveSheet()->getHighestColumn();
$colNumber = PHPExcel_Cell::columnIndexFromString($highestColumm);
$arrayCount = count($allDataInSheet);
for($i=4;$i<=$arrayCount;$i++){
$datum = $objPHPExcel->getActiveSheet()->getCell('A'.$i)->getValue();
$prva = $objPHPExcel->getActiveSheet()->getCell('C'.$i)->getValue();
$zadnja = $objPHPExcel->getActiveSheet()->getCell('D'.$i)->getValue();
$najvisa = $objPHPExcel->getActiveSheet()->getCell('E'.$i)->getValue();
$najniza = $objPHPExcel->getActiveSheet()->getCell('F'.$i)->getValue();
$prosjecna = $objPHPExcel->getActiveSheet()->getCell('G'.$i)->getValue();
$promjena = $objPHPExcel->getActiveSheet()->getCell('H'.$i)->getValue();
$broj_transakcija = $objPHPExcel->getActiveSheet()->getCell('I'.$i)->getValue();
$kolicina = $objPHPExcel->getActiveSheet()->getCell('J'.$i)->getValue();
$promet = $objPHPExcel->getActiveSheet()->getCell('K'.$i)->getValue();
var_dump($datum);
exit;

It does get the date..... that isn't a random number, that's an MS Excel serialized datetime stamp. In the same way that you might use a unix timestamp in PHP, and then use the date() function to format that, MS Excel uses its own timestamp value, which is a count of the number of days since 1st January 1900 (or 1st January 1904 if created on a Mac). To display it formatted, you need to apply a number format mask.
The Cell's getValue() method will return the raw value from the cell, but getFormattedValue() will return the value with the number format mask applied
There are also documented methods (e.g. PHPExcel_Shared_Date::ExcelToPHP($msExcelSerializedTimestamp)
) for converting between the MS Excel timestamp and unix timestamp or DateTime objects, and for checking whether a cell contains a date or not

Related

Import profile (birth date) from excel file to MySQL

I have structure table like: name varchar(15), gender smallint(1), birth_date date().
Controller:
public function actionImport()
{
$profile = new Profile();
$inputFile = 'files/profile.xlsx';
try{
$inputFileType = \PHPExcel_IOFactory::identify($inputFile);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($inputFile);
}catch(Exception $e){
die('error');
}
$sheet = $objPHPExcel->getSheet(0);
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
for($row = 1; $row <= $highestRow; $row++)
{
$rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row, Null, TRUE, FALSE);
if($row == 1){
continue;
}
$profile->name = $rowData[0][0];
$profile->gender = $rowData[0][1];
$profile->birth_date = $rowData[0][2];
$profile->save();
}
}
File: profile.xlsx
Data import success, but birth_date still 0000-00-00.
I try to print_r display like this:
Data saved in table like this:
A getValue() call on a field containing a date should return a value like 41959.... that is, an MS Excel serialized datetime stamp based on the number of days since 1st January 1900 (or 1st January 1904 if the file was created using the Mac version of MS Excel), and (by default) rangeToArray() uses a getValue() call.
To get a formatted date string, you need to call getFormattedValue() instead; and PHPExcel then uses the number format mask for that cell to format the date according to that mask. You can set rangeToArray() to do this for you by setting the $formatData argument to true.
$rowData = $sheet->rangeToArray('A'.$row.':'.$highestColumn.$row, Null, TRUE, TRUE);
This will format all cells as they appear in the spreadsheet in Excel itself.
Alternatively, PHPExcel does provide functions to convert date values between Excel timestamps and unix timestamps, or PHP DateTime objects, and you could use those instead:
$profile->birth_date = PHPExcel_Shared_Date::ExcelToPHPObject($rowData[0][2])
->format('Y-m-d');
Dependence of your image, you try to save int number in date
field...so that the error is gone....
To resolve issue, you need to change number to date like this Y-m-d such as: 1991-11-20, this is MySQL date format, or you need to change MySQL field type to int if you need to save this number in database.
In PHP:
echo date('Y-m-d');
And you can convert date from unix by this:
$unixtime = 1307595105;
echo $time = date("Y-m-d", $unixtime);
for your example:
$profile->birth_date = date("Y-m-d", ($rowData[0][2] - 25569) * 86400);
OR
$profile->birth_date = date('Y-m-d', PHPExcel_Shared_Date::ExcelToPHP($rowData[0][2]));

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.

Custom date format in PHPExcel

In my excel file I am building from PHP the first row is the header one. I need to put there several dates as column header. Each date is (in dd/mm/yyyy format) 15/mm/yyyy starting from 15/01/2007 and ending with 15/12/2018 stepping month by month.
My code is this:
for($anno = $annoMin; $anno<=$annoMax; $anno++){
for($mese = 1; $mese <= 12; $mese++){
$mese = sprintf("%02s", $mese);
$periodo = '15/'.$mese.'/'.$anno;
$periodo = strtotime($periodo);
$periodo = PHPExcel_Shared_Date::PHPToExcel($periodo);
array_push($header_array,$periodo);
}
}
I build the date as a string, convert it into a unix timestap, convert it into an excel date and push it into the $header_array.
Then I draw the cells in the excel:
$ews->fromArray($header_array, ' ', 'A1');
Finally I format the cells where there is a date as:
$ews->getStyle('U1:EJ1')
->getNumberFormat()
->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY);
ISSUES ARE:
Actually my code is returning 'False' for each cell with a date;
I need to add a custom mask that is not listed in the PHPExcel library: MM/YYYY to be shown in each cell.
For the first issue: I have checked different SO questions and followed mainly this one. with no luck.
Problem is here:
$periodo = '15/'.$mese.'/'.$anno;
$periodo = strtotime($periodo);
which would give a string values of 15/1/2015, 15/2/2015... ``15/12/2015that you're then attempting to convert to a unix timestamp usingstrtotime()`.
If you read the PHP Docs on date formats used by the strtotime() function, you'll see that a / separator tells PHP that the date string is US date format.... i.e. mm/dd/yyyygiving a month value of15` in every case, and (of course) there is no month 15
Either use a dash (-) rather than a / to indicate European (dd-mm-yyyy) rather than US date format
$periodo = '15-'.$mese.'-'.$anno;
$periodo = strtotime($periodo);
or re-order the values to use US format
$periodo = $mese.'/'.'15/'.$anno;
$periodo = strtotime($periodo);
And for the second part of your question.... you can supply almost any format mask that MS Excel recognises, you're not restricted to the built-in formats; so:
$ews->getStyle('U1:EJ1')
->getNumberFormat()
->setFormatCode('mm/yyyy');
The format code is simply a string value

Why coming dates from csv display as numbers in php side?

Well, I don't know why it's happening but my following date field of excel displayed as numbers not even timestamp.
Screenshot of my excel csv file date field.
Now, when I read CSV date field will shows this date as following numbers in combobox using php and I don't know why it's displaying like that and what should I do to convert back to my csv file date.
Following date is displayed when I do data[$k] to do csv file reading:
41724 and 41731 and so on in combobox. What to do?
My code:
while($data = fgetcsv($handle, 1000, ",")) {
if($row == 10) {
break;
}
else {
if($mycount == 0) {
$mycount = 1;
$field_name = $data[$k];
$tot_combo = $tot_combo + 1;
} else {
**$user_data[]** = $data[$k]; //where date coming here
}
$row = $row+1;
}
}
So after did some more research I found in csv excel file my date column is assigned as date and when reading file in php it convert that date column to text which will return me 41708 not 10/03/2014 any idea how to achieve this Thanks
Because that number is an MS Excel serialized timestamp, it's how MS Excel stores date values and then uses a number format mask to render them as a human readable date.
A quick and dirty conversion to a PHP DateTime object:
function ExcelToPHPObject($excelDateTime = 0) {
$calendarBaseLine = '1899-12-30';
if ($excelDateTime < 60) {
// 29th February will be treated as 28th February
++$excelDateTime;
}
return (new \DateTime($calendarBaseLine, new \DateTimeZone('UTC')))
->modify('+' . floor($excelDateTime) . ' days')
->modify('+' . floor(fmod($excelDateTime, 1) * 86400) . ' seconds');
}
This function will return a PHP DateTime object (assumes MS Excel Windows 1900 calendar), and you can then use the DateTime object's format() method to format the date/time however you want, so:
$excelDateTime = 41724;
echo ExcelToPHPObject($excelDateTime)->format('Y-m-d H:i:s');

Mismatch when converting Excel date numbers to Unix Timestamp using 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.

Categories