Why is the date and time conversion different on different dates? - php

I have four dates with different dates but the same time:
2019-03-02 20:00:00
2019-03-05 20:00:00
2019-03-10 20:00:00
2019-03-18 20:00:00
Those dates and times are in UTC. I want to convert it to a timezone, for example Los Angeles.
Here is the code:
$dateTime = '2019-03-02 20:00:00';
$dt = new DateTime($dateTime, new DateTimeZone('UTC'));
$dt->setTimeZone(new DateTimeZone('America/Los_Angeles'));
$new = $dt->format('Y-m-d H:i:s');
echo $new;
The dates with 2019-03-10 and 2019-03-18 shows up as different times. The answer is because on March 10, it will be 1 hour ahead due to day light savings.
Here is what it comes out with:
2019-03-02 12:00:00
2019-03-05 12:00:00
2019-03-10 13:00:00
2019-03-18 13:00:00
My question is, how can I format my date using the code above and NOT factor in day light saving. I simply want to convert my time without daylight savings. How can I do that? Here is my expected output:
2019-03-02 12:00:00
2019-03-05 12:00:00
2019-03-10 12:00:00
2019-03-18 12:00:00
They are all at 12:00:00.

I simply want to convert my time without daylight savings.
Sorry, but that line of thinking is problematic. Daylight saving time is not something that is optional for the people in the US Pacific time zone (represented by America/Los_Angeles). They don't get a choice of whether to opt in or opt out.
If you are trying to handle some stated business requirement like "Don't worry about DST" - sorry, but you should push back on that. Otherwise your code will generate incorrect results for most of the year. (In the US, the daylight period is actually longer that than standard period!)
However, if what you are really after is not the time in US Pacific time zone, but simply the time at a fixed offset of UTC-8, then instead of America/Los_Angeles, use the time zone Etc/GMT+8 (note that the sign is inverted intentionally). This will use UTC-8 no matter what time of the year you are talking about.
Do keep in mind that the Etc/GMT* zones are primarily intended for edge cases such as time onboard ships at sea. If you simply want to track time in some other part of the world, then chose the appropriate time zone for that location. For example, the Pitcairn Islands use UTC-8 all year long and call it PST, and their time zone identifier is Pacific/Pitcairn.
Refer to the full list of time zones here.
As far as the point you made about 20:00:00 UTC being 12:00:00 PST but 13:00:00 PDT - indeed that is the reality of the situation. If you are tracking 24 hour periods one after another, then there's no way to avoid this fact. Even if instead you tracked "Noon in Pacific Time" each day, then you'd get different corresponding UTC times before and after the transitions.
While UTC days are 24 hours, the transition days in US Pacific time are 23 hours long when we switch from PST to PDT in the spring, and 25 hours long in the fall when we switch from PDT to PST in the fall.
And if you think that is complicated, consider that not every time zone has a 1 hour DST delta. Lord Howe Island in Australia (Australia/Lord_Howe) has a 30 minute delta. They are UTC+10:30 during standard time, and UTC+11 during daylight time.

Since PHP DateTime objects always take daylight savings time into account, you need to make the conversion by subtracting the time difference when daylight savings time is not in effect. This code should do what you want:
$utctime = new DateTime('2019-01-01', new DateTimeZone('UTC'));
$localtime = new DateTime('2019-01-01', new DateTimeZone('America/Los_Angeles'));
$diff = $localtime->diff($utctime);
foreach ($dates as $date) {
$dt = new DateTime($date, new DateTimeZone('UTC'));
$dt->add($diff);
echo $dt->format('Y-m-d H:i:s');
}
Output:
2019-03-02 12:00:00
2019-03-05 12:00:00
2019-03-10 12:00:00
2019-03-18 12:00:00
Demo on 3v4l.org
Update
As was pointed out by #MattJohnson, there exists a timezone Etc/GMT+8 which refers to 8 hours earlier than GMT (regardless of daylight savings time). You can use that timezone to adjust your times:
$west_coast = new DateTimeZone('Etc/GMT+8');
foreach ($dates as $date) {
$dt = new DateTime($date, new DateTimeZone('UTC'));
$dt->setTimeZone($west_coast);
echo $dt->format('Y-m-d H:i:s') . "\n";
}
The output is the same as above. Demo on 3v4l.org

Related

Converting time in php and converting it on google shows different results which is correct?

I converted the time 18:00:00 pm UTC time to Los angeles time and the output of the program was 10 AM and then I searched this on google "18:00:00 pm UTC to Los angeles time" and google showed me the result 11:00 AM
https://i.imgur.com/H5po3fD.png
I am confused whats correct here. Similarly if I convert converted_date_time('2021-11-08 04:54:15') UTC to los angles time then the program output shows the time 8:54 AM but on google it shows 9:54 AM.
date_default_timezone_set("America/Los_Angeles");
echo date_default_timezone_get();
echo '<br>';
function converted_date_time($dt) {
$datetime = new DateTime($dt, new DateTimeZone('UTC'));
$datetime->format('Y-m-d H:i:s');
$datetime->setTimezone(new DateTimeZone(date_default_timezone_get()));
return $datetime->format('Y-m-d H:i:s');
}
//convert time to utc
echo converted_date_time('2021-11-08 18:00:00').'<br>';
It depends on the date. Daylight savings don't apply to UTC, so in summer, 18:00 UTC will be 11:00 Pacific Time (PDT, Pacific Daylight Time), while in winter, 18:00 UTC will be 10:00 Pacific Time (PST, Pacific Standard Time).
Most likely Google shows you the current result (with Daylight Savings, so +1 hour), while at your date (November 8), daylight savings is off.
In other words, today, 18:00 UTC is 11:00 in Los Angeles, but next month, 18:00 UTC will be 10:00 in Los Angeles.
You can try by yourself, those two should give you different results:
echo converted_date_time('2021-11-08 18:00:00').'<br>';
echo converted_date_time('2021-09-08 18:00:00').'<br>';

PHP convert date from EEST to UTC returns incorrect time by one hour

My PHP is converting the date incorrectly, the answer is off by one hour, I think the problem is that PHP thinks Europe/Vilnius is EEST time at this time, which should mean UTC+3, but its actually UTC+2 at this time. Any help how to solve this would be much appreciated. Have a great day!
My code:
$timezone = new DateTimeZone('Europe/Vilnius');
$UTCtimezone = new DateTimeZone('UTC');
$UTC_time = new DateTime($raw_date, $timezone); --> $raw_date is '2020-04-18 13:48:22'
At this time the date reads = 2020-04-18 13:50:05 EEST which is correct except for the EEST bit.
$UTC_time->setTimezone($UTCtimezone);
At this time date reads 2020-04-18 10:50:05 UTC which is incorrect now, because UTC time now should be 2020-04-18 11:50:05
Lots of karma points to anyone with any suggestions!
Europe/Vilnius is using EET (Eastern European Time) right now (2020-03-19), which is UTC+2.
On 2020-03-29 Europe/Vilnius will change to Daylight Saving Time EEST (Eastern European Summer Time), which is UTC+3.
Your example date 2020-04-18 is after that change, so it'll be 3 hours ahead of UTC.
Try todays date and the same code should show a 2 hour difference between Europe/Vilnius and UTC.

In PHP, how to get UTC date for calendars that include Day Light Savings (DLS)

I'm not sure if the gmdate() function in PHP captures the Day Light Savings reality of the world. For example this code:
<?php
echo "<pre>";
echo "Current timezone: ", date_default_timezone_get(), "\n";
$future_date = 'Nov 03, 2019 03:30 PM EDT';
$future_UTC = gmdate('M d, Y h:i A T', strtotime($future_date));
echo "
New York Date: $future_date
GMT/UTC time: $future_UTC
";
?>
Prints out this:
Current timezone: UTC
New York Date: Nov 03, 2019 03:30 PM EDT
GMT/UTC time: Nov 03, 2019 07:30 PM GMT
This is technically incorrect, because on Nov 3 at 2pm, the DLS will switch and the time in GMT/UTC will actually be 08:30 PM, instead of the erroneous 07:30 PM that PHP is showing (based on today's DLS).
Is there any way to automatically get the right time for future dates?
There are many errors here, starting with the title of your question:
how to get UTC date for calendars that include Day Light Savings (DLS)
UTC is well-defined, and has no daylight savings time. If you're in a different timezone, and in a locality that has daylight savings time, then you're not in UTC anymore. So, the question is nonsensical to begin with.
$future_date = 'Nov 03, 2019 03:30 PM EDT';
EDT means "Eastern Daylight Time", so in this case you're forcing a particular interpretation, regardless of date. You'll note that if you change it to EST (Eastern Standard Time), you'll get a different result.
You probably want America/New_York instead of EDT. See also: https://www.php.net/manual/en/timezones.php
This is technically incorrect, because on Nov 3 at 2pm, the DLS will switch
No. 2:00 AM.
Is there any way to automatically get the right time for future dates?
Stop feeding PHP broken data and ambiguously formatted dates. We have date/time standards for a reason, such as ISO8601. Date/time is a complicated thing. Computers can't read minds, and don't know what you intended when you gave it the wrong date for a specific type of timezone with daylight savings time.

PHP setTimeZone timezone conversion issues - peculiarities due to BST (GMT+1)

I have a datetime field stored in my mysql database which contains a time for an event set in UK time. In the example used below this time is 09:00.
I am attempting to display this time also in West Coast and East Coast USA timezones.
I believe I'm using the php DateTime 'setTimeZone' function correctly - however the results coming back are an hour out for both timezones
$online->getTimeByZone('America/Los_Angeles'); // Returns 02:00
$online->getTimeByZone('America/New_York'); // Returns 05:00
public function getTimeByZone($timezone = 'Europe/London') {
$date = $this->getDateField('start_time', 'Y-m-d H:i:s'); // 2017-10-30 09:00:00
$datetime = new DateTime($date, new DateTimeZone('Europe/London'));
$datetime->setTimeZone(new dateTimeZone($timezone));
return $datetime->format('H:i');
}
I am assuming from the hour difference this is going to be related to the UK observing Daylight Savings Time - but I would have expected as I'm initiating the DateTime object with 'Europe/London' this to be factored in.
Any ideas?
You have picked an example date that occurs in the small window when North America is still observing "Daylight Saving Time", but the UK is not observing "Summer Time": UK clocks change on the last Sunday in October, but USA and Canadian clocks on the first Sunday in November.
During this overlap week, America/New_York time is UTC-4 ("Eastern Daylight Time"), and Europe/London time is UTC+0 ("Greenwich Mean Time"). Consequently, "2017-10-30 09:00:00 Europe/London" is indeed "2017-10-30 05:00:00 America/New_York".
If you pick a date a week earlier, the offsets will be UTC-4 and UTC+1 ("British Summer Time"); a week later, they will be UTC-5 ("Eastern Standard Time") and UTC+0; so for most of the year, you would be correct that the expected difference would be 5 hours.
There is another two weeks in March where North America changes its clocks earlier, so again there will be a 4-hour offset instead of 5.
(The same of course applies to the America/Los_Angeles timezone, which will be 6 instead of 7 hours away during these three weeks.)

Convert date and time from UTC to IST and vice versa in PHP

I am working on a project which saves the time in UTC zone. I want to display the time in Asia/Kolkata zone in the front end.
$createdAt = '2017-03-16 23:21:56';
/* The indian time was 2017-03-17 11:52 when the record was placed, so after converting it to Asia/Kolkata it should display 2017-03-17 11:52 (seconds does not matter) */
My PHP code to convert it into Asia/Kolkata
$createdAt = '2017-03-16 23:21:56';
$dateFrom = new DateTime($createdAt, new DateTimeZone('America/Chicago'));
$dateFrom->setTimezone(new DateTimeZone('Asia/Kolkata'));
$IST = $dateFrom->format('Y-m-d H:i:s');
The output is 2017-03-17 09:51:56 instead of 2017-03-17 11:52:56 . The output shows 2 hours before the actual time. I can't figure it out.
Your suggestions will help me a lot.
If your input date/time is in the Chicago time zone, then one should take into account the DST. The change occurred on 12th March 02:00 local time so your input (assuming $createdAt is correct) is already in DST regime (i.e., UTC -05:00).
Since Kolkata is UTC+05:30 (and there is no DST adjustment), the total difference for your particular input is 10:30 which justifies the output of 2017-03-17 09:51:56.

Categories