After an hour exploring Stack Overflow, I'm more confused than ever (and based on the number of posts, I'm probably missing something painfully obvious). All I want to do is add n minutes to an existing date/time string (formatted as $start = '2022-09-10T09:00:00-07:00') WITHOUT losing the time zone.
Based on my reading, it looks like I need to use 'date' and 'strtotime' but when I do I lose the time zone. For example ...
$start = date('m:d:y H:i:s', strtotime($start . ' 90 minutes'));
...returns '09:10:22 14:30:00'
When I try adding formatting like this to get the exact format I'm looking for...
$start = date(DATE_W3C, strtotime($start . ' 90 minutes'));
...it returns the correct format but changes the time zone: '2022-09-10T14:30:00 00:00'
All I am trying to do is to take '2022-09-10T09:00:00-07:00' and add 90 minutes to make it '2022-09-10T10:30:00-07:00'. What am I missing?
CodePudding user response:
Although there's nothing wrong with the date
and strtotime
functions, they force you to deal with strings and ints which makes things muddy. Instead, if you can elevate that to a higher level thing, specifically the DateTime
(or DateTimeImmutable
) you can reason about things easier.
$date = new DateTime('2022-09-10T09:00:00-07:00');
$date->modify(' 5 minutes');
echo $date->format(DateTime::RFC3339);
// Result: 2022-09-10T09:05:00-07:00
Demo here: https://3v4l.org/FpQlf
CodePudding user response:
Chris Haas' answer points in the right direction, but doesn't adequately explain what's wrong in the code from the question.
strtotime
takes into account a time zone in the date expression just like DateTime
does. DateTime
saves this time zone correctly in the object. strtotime
always converted the time zone to the UTC and a time stamp is returned as the result.
Date
, on the other hand, always returns the date from the server's default time zone. The following code clarifies this:
$start = '2022-09-10T00:00:00-07:00'; //TZ=-7:00 Time: 00:00
$timeStamp = strtotime($start);
echo "start as UTC: ".gmdate(DATE_W3C,$timeStamp)."\n";
//start as UTC: 2022-09-10T07:00:00 00:00
date_default_timezone_set('Europe/Berlin'); //my local timezone
echo "start as Localtime: ".date(DATE_W3C,$timeStamp)."\n";
//start as Localtime: 2022-09-10T09:00:00 02:00
The date expression $start has the time 00:00 and the time zone -07:00. The UTC time output from the time stamp has the time 07:00 (and the time zone 00:00 = UTC). When outputting with Date, the local time is then converted. Output 09:00 for the time and 02:00 for the Berlin time zone.
Demo: https://3v4l.org/v7231