Laravel Carbon how to change timezone without changing the hour
Use the shiftTimezone()
method instead of setTimezone()
.
If you call setTimezone()
on an existing instance of Carbon,
it will change the date/time to the new timezone, for example:
$datetime = Carbon::createFromFormat('Y-m-d H:i:s', '2020-09-15 23:45:00');
echo $datetime->toAtomString() . "\n";
// 2020-09-15T23:45:00+00:00
$datetime->setTimezone('America/Los_Angeles');
echo $datetime . "\n";
// 2020-09-15T16:45:00-07:00
However, calling shiftTimezone()
instead will set the
timezone without changing the time. Lets try it again from the start:
$datetime = Carbon::createFromFormat('Y-m-d H:i:s', '2020-09-15 23:45:00');
echo $datetime->toAtomString() . "\n";
// 2020-09-15T23:45:00+00:00
$datetime->shiftTimezone('America/Los_Angeles');
echo $datetime->toAtomString() . "\n";
// 2020-09-15T23:45:00-07:00
Of course you can chain the methods together as well:
$datetime = Carbon::createFromFormat('Y-m-d H:i:s', '2020-09-15 23:45:00')
->shiftTimezone('America/Los_Angeles');
echo $datetime->toAtomString() . "\n";
// 2020-09-15T23:45:00-07:00
You can also "shift" the timezone by passing the timezone as part of the
settings
array:
$datetime = Carbon::createFromFormat('Y-m-d H:i:s', '2020-09-15 23:45:00')
->settings(['timezone' => 'America/Los_Angeles']);
echo $datetime->toAtomString() . "\n";
// 2020-09-15T23:45:00-07:00
My response to this question will be a little different. For my situation, I had a date string that needed to be parsed as if it was the 0th hour (midnight) on the given day in a custom timezone - but all the dates in my database are tracked in UTC, so what I really needed to do was keep the date in UTC timezone, but give it kind a "reverse offset" of what the expected timezone was.
Situation: I get a datestring of "2020-09-02" that I will use to see if X records have a field that is on or after this same date; however, I am in the America/Chicago timezone which currently is -05:00 from UTC, so I need to adjust the UTC version of this date string to be 2020-09-02 05:00 to accurately account for midnight in my timezone.
To do that, I needed to parse the datestring as being in the America/Chicago timezone, and then change the timezone to UTC:
$value = "2020-09-02"
Carbon::parse($value . ' America/Chicago')->tz('UTC')
A better and simpler way would be:
$carbon = new Carbon('YYYY-MM-DD HH:II:SS', 'America/Los_Angeles');
NOTE: Don't forget to add dependency use \Carbon\Carbon;
.
I think that what you'r looking for is this:
Carbon::createFromFormat('Y-m-d H:i:s', $some_date, 'UTC')
->setTimezone('America/Los_Angeles')
First, you set the timezone you initially have, so if you store your date in the database as UTC, then set the default timezone to UTC, then use ->setTimeZone('Valid/Timezone')
to make the change from what you'v had to the new timezone.