Home > Blockchain >  PHP Add n Minutes to Time/Date string and RETAIN timezone
PHP Add n Minutes to Time/Date string and RETAIN timezone

Time:08-27

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

  • Related