By using Maatwebsite/Laravel-Excel to import excel sheet, here I faced an issue date time column of the excel sheet returns float value. How to solve this? Example : Conside
That "floating number" is an excel timestamp, that way it stores the date and time data internally.
for example:
123213.0: it's just a date
213233.1233: is a date and time
0.1233: it's one hour
To solve this you must convert that floating point number to a date.
if your need involves resolving datetime fields dynamically, I have written a method that is responsible for automatically detecting if the value is a datetime dynamically (regardless of whether or not you know if there will be a datetime in that column) or I have tried various data types and it works fine
/**
* @param Cell $cell
* @param $value
*
* @return boolean;
*/
public function bindValue(Cell $cell, $value)
{
$formatedCellValue = $this->formatDateTimeCell($value, $datetime_output_format = "d-m-Y H:i:s", $date_output_format = "d-m-Y", $time_output_format = "H:i:s" );
if($formatedCellValue != false){
$cell->setValueExplicit($formatedCellValue, DataType::TYPE_STRING);
return true;
}
// else return default behavior
return parent::bindValue($cell, $value);
}
/**
*
* Convert excel-timestamp to Php-timestamp and again to excel-timestamp to compare both compare
* By Leonardo J. Jauregui ( @Nanod10 | siskit dot com )
*
* @param $value (cell value)
* @param String $datetime_output_format
* @param String $date_output_format
* @param String $time_output_format
*
* @return $formatedCellValue
*/
private function formatDateTimeCell( $value, $datetime_output_format = "Y-m-d H:i:s", $date_output_format = "Y-m-d", $time_output_format = "H:i:s" )
{
// is only time flag
$is_only_time = false;
// Divide Excel-timestamp to know if is Only Date, Only Time or both of them
$excel_datetime_exploded = explode(".", $value);
// if has dot, maybe date has time or is only time
if(strstr($value,".")){
// Excel-timestamp to Php-DateTimeObject
$dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
// if Excel-timestamp > 0 then has Date and Time
if(intval($excel_datetime_exploded[0]) > 0){
// Date and Time
$output_format = $datetime_output_format;
$is_only_time = false;
}else{
// Only time
$output_format = $time_output_format;
$is_only_time = true;
}
}else{
// Only Date
// Excel-timestamp to Php-DateTimeObject
$dateTimeObject = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($value);
$output_format = $date_output_format;
$is_only_time = false;
}
// Php-DateTimeObject to Php-timestamp
$phpTimestamp = $dateTimeObject->getTimestamp();
// Php-timestamp to Excel-timestamp
$excelTimestamp = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel( $phpTimestamp );
// if is only Time
if($is_only_time){
// 01-01-1970 = 25569
// Substract to match PhpToExcel conversion
$excelTimestamp = $excelTimestamp - 25569;
}
/*
// uncoment to debug manualy and see if working
$debug_arr = [
"value"=>$value,
"value_float"=>floatval($value),
"dateTimeObject"=>$dateTimeObject,
"phpTimestamp"=>$phpTimestamp,
"excelTimestamp"=>$excelTimestamp,
"default_date_format"=>$dateTimeObject->format('Y-m-d H:i:s'),
"custom_date_format"=>$dateTimeObject->format($output_format)
];
if($cell->getColumn()=="Q"){
if($cell->getRow()=="2"){
if(floatval($value)===$excelTimestamp){
dd($debug_arr);
}
}
}
*/
// if the values match
if( floatval($value) === $excelTimestamp ){
// is a fucking date! ;)
$formatedCellValue = $dateTimeObject->format($output_format);
return $formatedCellValue;
}else{
// return normal value
return false;
}
}
Known bug, see https://github.com/Maatwebsite/Laravel-Excel/issues/404 for details.
But basically, when using chunk() to read the cells in, it fails to convert Excel's datetime format from a float into a Carbon date object.
There is currently no fix, You can work around this by calling config before the call to load:
config(['excel.import.dates.columns' => [
'deleted_at',
'updated_at'
]]);
Excel::filter('chunk')->load($file)->chunk(100 function($rows) { ... });
If you're not using the chunk filter, then see http://www.maatwebsite.nl/laravel-excel/docs/import#dates on how to explicty set formats on cells (setDateColumns()), but those should be converting automatically unless you change the defaults.
Change the format your import file to .csv and format the date column to your required date format (dd-mm-yyyy)
This only happend when use chunk. This issue could be solved by:
$UNIX_DATE = ($row->DOB - 25569) * 86400;
$date_column = gmdate("d-m-Y H:i:s", $UNIX_DATE);