Phpspreadsheet - Time cell retrieved as float - php

I have an excel file which has a time input.
Mar 01, 2018 | Thursday | 8:00 AM | 5:00 PM
Mar 02, 2018 | Friday | 8:00 AM | 5:00 PM
But when my code tries to read those cells, the output becomes a float (for example 8:00 AM becomes 0.33333333333333). This is my code
$date = $sheet->getCell("A".$row)->getValue();
$time_in = $sheet->getCell("C".$row)->getValue();
$time_out = $sheet->getCell("D".$row)->getValue();
echo "date: ".$date. //Mar 01, 2018
" time_in: ".$time_in. //becomes 0.333333333333333
" time_out: ".$time_out; //becomes 0.708333333333333
How can I make the output as is without the phpspreadsheet changing the value? I have tried looking at the phpspreadsheet documentation but I haven't found a solution.

Thankfully I have found the answer just now.
$in = \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimestamp($time_in);
echo gmdate("g:i a", $in);
Hopefully, this could be useful for others.

Formart the data before you read it.
For example:
cell data 2020/10/13 19:00:00
Access directly will get 44117.791666667
$sheet->toArray();
Format before access will get 2020-10-13 19:00:00
$row_num = $sheet->getHighestDataRow();
$sheet->getStyle("H1:H$row_num")->applyFromArray(array("numberFormat"=>array("formatCode"=>'yyyy-mm-dd hh:mm:ss'))); // H is the datatime row
$sheet->toArray();

Related

Using strtotime with TimeZone

I have a problem. I want to convert this DateTime: 2018-10-28 02:00:00 to a TimeStamp. Now the TimeStamp I am looking for is: 1540684800, but with my code I get this TimeStamp: 1540688400. I know it has something to do with my TimeZone, but I don't know how I can fix this.
I live in the Netherlands in Amsterdam.
Here is my code:
$LoopDateTime = "2018-10-28 02:00:00";
$search_key = (strtotime($LoopDateTime)*1000);
Can someone help me?
The time zone identifier for Amsterdam is Europe/Amsterdam and 1540688400 is the correct timestamp. There's surely an online tool to check but you can also verify it from PHP itself:
$date = new DateTime("#1540688400");
$date->setDateTimeZone(new DateTimeZone('Europe/Amsterdam'));
echo $date->format('r'); // Sun, 28 Oct 2018 02:00:00 +0100
However your code is not robust because depends on the configured timezone. You can just set it explicitly in a number of ways, e.g.:
$LoopDateTime = "2018-10-28 02:00:00";
$search_key = strtotime($LoopDateTime . ' Europe/Amsterdam') * 1000;
var_dump($search_key); // int(1540688400000)
Or:
date_default_timezone_set('Europe/Amsterdam');
$LoopDateTime = "2018-10-28 02:00:00";
$search_key = strtotime($LoopDateTime) * 1000;
var_dump($search_key); // int(1540688400000)
P.S. If I'm not wrong Sunday 28 Oct 2018 02:00:00 +0100 is the exact moment when most Europe has just switched from CEST (+0200) to CET (+0100).

Changing time format from 9:00am to 09:00am in php

Iam having variable with value 9:30 am - 12:00 pm i.e
$val=$shift (o/p 9:30 am - 12:00pm)
I want to convert it to 09:30 am - 12:00pm, i mean i need to add 0 infront of number if time having one digit
If you are using date function then you can format time using h.
For example
echo date('h:ia'); // output 09:50am
See Referance
If you have values from DataBase as you mentioned in comment then you need to apply PHP's built-in function strtotime() before formatting the time.
For Example
echo date( 'h:ia', strtotime('9:30 am') ); // output 09:50am
Assuming you are saving your time in your database as a string as 9:30 am - 12:00pm you can just split them. Then format each data.
$val= "9:30 am - 12:00pm";
$splittedString = explode('-', $val);
$time1 = date('h:ia',strtotime($splittedString[0]));
$time2 = date('h:ia',strtotime($splittedString[1]));
echo $time1." - ".$time2;
Try
echo date('h:ia',strtotime("9:30 am"))." - ".date('h:ia',strtotime("12:00pm"));

PHP - Best way to query database or collection by date and do sub calculations

I have a collection/db of around 4k elements and each have a datetime and value e.g :
DATE Value
2017-01-01 17:00 994.44
2017-01-01 18:00 998.56
2017-01-01 19:00 1231
2017-01-01 20:00 63546
2017-01-01 21:00 64534
2017-01-01 22:00 768
2017-01-01 23:00 74575
2017-01-02 0:00 76574
2017-01-02 1:00 345634
2017-01-02 2:00 7567
2017-01-02 3:00 8534
2017-01-02 4:00 1010.62
2017-01-02 5:00 647445
I want to get the time for each day that had the lowest value e.g for 2017-01-02 , i should get 2
Basically an array :
2017-01-02 => 2
2017-01-03 => 5
...
I'm not sure about the best way to query and run these sub calculations .
One way i was considering would be to query the table for each specific date i.e : "2017-01-02" and then calculate .
However i think that would be overkill in this case and also i don't know about the specific dates .
right now , i'm getting the entire table into a collection (using Laravel) :
$data = TableX::all();
Try this one:
$data = TableX::select(
DB::raw('DATE_FORMAT(date, "%Y-%m-%d") AS date_formatted'),
DB::raw('DATE_FORMAT(date, "%H-%i") AS time_formatted'),
DB::raw('MIN(value) AS min_value')
)
->groupBy('date_formatted')
->get();
To access the result:
if (count($data) > 0) {
foreach ($data as $row) {
var_dump($row->date_formatted);
var_dump($row->time_formatted);
}
}

need to store date as per user timezone in php

i have simple php script where i have this variable
$date = date('Y-m-d', time());
The Problem: The variable is storing date as per my server timezone.
What is want: I want to store date as per user time zone, take a look into
example below:
1- tom checkin from USA
2- jenne checkin from Asia
since there is 12 hrs. difference so the date will be different too sometime
here is found some example but it's not dynamic
Converting GMT time to local time using timezone offset in php
offset = '-0500';
$isDST = 1; // Daylight Saving 1 - on, 0 - off
$timezoneName = timezone_name_from_abbr('', intval($offset, 10) * 36, $isDST);
$timezone = new DateTimeZone($timezoneName);
Then you can use it in a DateTime constructor, e.g.
$datetime = new DateTime('2012-04-21 01:13:30', $timezone);
Now what exactly i am looking,
1- in case of TOM $date should be 18
11:38 PM
Tuesday, 18 April 2017 (GMT-5)
Time in Chicago, IL, USA
2- in case of jenne $date should be 19
9:40 AM
Wednesday, 19 April 2017 (GMT+5)
Time in Lahore
difficult writing code in the comments section so i posted a working answer for you here
<?php
// here $usertimezone should be set = to what you have in your database
$usertimezone="Asia/Shanghai";
date_default_timezone_set('"'.$usertimezone.'"');
//new date and time
$ndate= new datetime();
//split into date and time seperate
$nndate =$ndate->format("Y-m-d");
$nntime= $ndate->format("H:i:S");
//here you can test it
echo $nndate;
echo $nntime;
?>
Use this function date_default_timezone_set for setting timezone, From this function you can set the timezone according to user and then get the required format.
Examples
<?php
date_default_timezone_set("new/timezone");//set the name of timezone here example Asia/Kokata
echo $date= date("Y-m-d H:i:s");

Zend_Date, ISO_8601, date parsing and local system clock

I have a strange problem with Zend_Date object.
It seems that setters perform different operations with different system clock dates.
Let's assume that system date is 28 January 2013, following code:
$now=new Zend_Date(Zend_Date::ISO_8601);
$now->now();
echo '<br/>now: ' . $now->toString();
echo '<br/>now->day: ' . $now->get(Zend_Date::DAY);
echo '<br/>now->month: ' . $now->get(Zend_Date::MONTH);
echo '<br/>now->year: ' . $now->get(Zend_Date::YEAR);
$end=new Zend_Date('2013-02-25 14:23:34', Zend_Date::ISO_8601);
echo '<br/>end: ' . $end->toString();
$end->setHour('23')->setMinute('59')->setSecond('59')->setDay($now->get(Zend_Date::DAY))->setMonth($now->get(Zend_Date::MONTH))->setYear($now->get(Zend_Date::YEAR));
echo '<br/>endAfterSetters: ' . $end->toString();
will produce following output:
now: 28-01-2013 14:04:28
now->day: 28
now->month: 01
now->year: 2013
end: 25-02-2013 14:23:34
endAfterSetters: 28-01-2013 23:59:59
But if you change system clock to 29 January 2013, output is different from expectations:
now: 29-01-2013 14:07:22
now->day: 29
now->month: 01
now->year: 2013
end: 25-02-2013 14:23:34
endAfterSetters: 01-01-2013 23:59:59
Last output is 01-01-2013 23:59:59, but should be 29-01-2013 23:59:59 !
It happens on PHP 5.3.2 and 5.3.16, Zend_Framework 10.7, latest Zend_Date 24880 version.
Everyting worked fine in the past.
Any ideas why it happens?
P.S.: I have also found jquery datatime plugin malfunciton while using it at 29,30,31 January... But i will describe it in other question.
Remember that your setters are called in sequence. So when you call setDay(29) you're telling it to change the date to 29th February 2013, which isn't a valid date, so it's rolling that over to make it 1st March 2013. Then you call setMonth(1), which changes the month to January, giving you 1st January 2013.
You can control this behaviour by passing the extend_month option to the Zend_Date constructor, see: http://framework.zend.com/manual/1.12/en/zend.date.overview.html#zend.date.options.extendmonth

Categories