Setting PHP DateTime doesn't appear to be observing TimeZones - php

I'm fairly new to PHP so forgive me if this is a stupid mistake that I haven't spotted
I've run into a problem where in our current system where we currently used strtotime and it was returning our date an hour ahead than it actually was set. E.g 1:15pm became 2:15pm when I set the timezone to be European rather than GMT.
I read that strotime had this problem but I can't get it to observe a different timezone if I try and set it.
So I tried working with PHPs DateTime instead.
The user enters the time and they select it as 1:15PM however we want to store it as 13:15. So I did this:
$t = DateTime::createFromFormat('h:i A', $venue['startTime']);
$t_24 = $t->format('H:i:s');
Then I try and create my Date object
$d = DateTime::createFromFormat('d-m-Y H:i:s', $venue['startDay'] . ' ' . $t_24);
$d->setTimezone(new DateTimeZone('America/New_York'));
echo ' ' . $d->getTimestamp();
Trying to set the timezone after the object is set because apparently it doesn't work if you add the timezone as the third argument in createFromFormat
My computers time is currently observing European time currently GMT+1 because we're observing daylight savings time in the UK, I select the time set on the through our system as 1:15pm and because I've set the timezone I expect the timestamp outputted equivalent to 7:15am as it's six hours behind European time, however when I convert the timestamp 1500639300 it's still equal to 2:15 PM. Probably done something stupid but can't quite figure out what? Any help would be appreciated :)

Timestamps have no time zone - they are always in UTC time. If you want to save timezone related data use another format! For example save in H:i:s, as you need it.

you can use gmdate() Function for this
<?php $current_time = gmdate('Y-m-d H:i:s'); ?>
http://php.net/manual/en/function.gmdate.php

Related

php - Different behaviour of `DateTimeImmutable` for the same datetime value in different format

Let's suppose we have this date 1972-12-31 23:59:59, if we get the TimeStamp for it from DateTimeImmutable object we will get this:
$formattedDate = '1972-12-31 23:59:59';
$ts = (new DateTimeImmutable($formatedDate))->getTimestamp(); // <- 94690799
The problem that if you try to revers the conversion, so it becomes from timestamp into formatted date:
$ts = 94690799;
$formattedDate =
(new DateTimeImmutable(sprintf('#%s', $ts)))->format('Y-m-d H:i:s'); // <- 1972-12-31 22:59:59
There is an hour gone in the second way.
So the million dolor question would be, which one of those timing is corresponding to the correct time?
Is this a bug? Or am I messing something in here?
When you create a DateTime object from a formatted string, it is created in your server's default timezone (see date_default_timezone_get). But Unix timestamps don't have a timezone - they're always in UTC. So if you write:
(new DateTimeImmutable('1972-12-31 23:59:59'))->getTimestamp();
then what you're really asking PHP is "How many seconds after 1970 in UTC was it, when it was that date + time in my current timezone". In your case, the server looks like it is running one hour ahead of UTC, hence the difference.
Crucially, when you do the inverse and create a DateTime object from a timestamp, the object's timezone is always set to UTC. There's a brief note about it on this manual page.
If you set the default timezone to UTC before running the code, you'll see that the output matches. I've added an example here: https://3v4l.org/2Rfp3

ISO date formats to wrong day

Short question but I can't get my finger on it. This piece of code:
$date = '2015-12-08T00:00:00+01:00';
echo date('D', strtotime($date));
returns Mon while
$date = '2015-12-08T00:00:00';
echo date('D', strtotime($date));
returns Tue. Why is that? The +01:00 is for the timezone, but that should not affect the day in my opinion.
First I've looked up that 08-12-2015 is in fact a Tuesday, so now we know the first one is incorrect.
PHP's date() is an Unix timestamp according to their own docs.
My belief is that adding the +1 as a timezone triggers the calculation to the +0 timezone (UTC) when asking for the day of the week and therefore returns 23:00 on monday as the current UTC time.
You can specify the timezone before executing the rest of the code: date_default_timezone_set('Europe/Amsterdam');
<?php
date_default_timezone_set('Europe/Amsterdam'); //this is an example of a +1 timezone, choose one from http://php.net/manual/en/timezones.php
$date = '2015-12-08T00:00:00+01:00';
echo date('D', strtotime($date) );
?>
strtotime will parse your date string using the supplied time zone or using the default timezone if unspecified. We can't see from the code you've posted what time zone your server is configured to, but once the date is parsed and converted to your time zone, the time may legitimately occur in the previous day, hence why you're seeing 'Mon'.
Either supply a time zone in the strtotime call via the now argument or set one globally with date_default_timezone_set.

How to get the UTC time in years and months

I want to know how I could get the UTC time in year and months?
I've scraped the UTC date and time from a website, but I have been to asked to show the full UTC format such as (2014-07-31 22:00:00), the problem I'm facing now is that our current time is 1 hour ahead than UTC time.
Here's the code I'm using:
$date_time = date("Y-m", $time_now) . "-". $wxInfo['DAY'] . " " . $wxInfo['HOUR'] . ":" . $wxInfo['MINUTE'] . ":00";
As you can see, for the Y-m(year and month) I use local time, but the DAY, HOUR, MINUTE values from the website which is in UTC. This $date_time is updated every half hour, if they update on "2014-07-31 23:00:00", our current time is "2014-08-01 00:00:00". so my code will output:
2014-08-31 23:00:00
How can I convert to the right UTC year and month?
Use DateTime() with DateTimeZone()
// Set time to local time "now"
$datetime = new DateTime();
// Change timezone to UTC
$datetime->setTimeZone(new DateTimeZone('UTC'));
// Echo datetime in desired format
echo $datetime->format('Y-m');
The solution John Conde suggested works well for displaying dates and times in a specific timezone.
In your case, I think you may want to set the timezone to UTC on the whole script, so all your calls to date() and DateTime->format() automatically use UTC. That is really simple to do: at the beginning of your script, write:
date_default_timezone_set('UTC');
PHP will then use UTC as a timezone everywhere. See manual: http://php.net/date_default_timezone_set

Get time at midnight(00:00:00) from a date

I am trying to convert a date to a timestamp at the exact midnight point.
To do this, I am using the following little function.
function converttotimestamp($date)
{
$date = str_replace('/', '-', $date);
$date = $date.' 00:00:00';
$date = DateTime::createFromFormat('m-d-Y H:i:s',$date);
return $date->getTimestamp();
}
So as you can see, I am attaching a midnight time at the end.
I tried using this as shown below
echo converttotimestamp('7/22/2014');
So as you would expect when you run this in a unix converter, you would get 1405987200.
But In my case it returns 1405976400 whicj translates to Mon, 21 Jul 2014 21:00:00.
Oh. I am in Kenya.
The reason you may be seeing a different time returned than the one you were expecting is likely because you haven't considered the relevant timezones. There are a couple different ways you can set the timezone. You can set it during runtime:
http://php.net/manual/en/function.date-default-timezone-set.php
You can set it in your PHP config file:
http://php.net/manual/en/datetime.configuration.php#ini.date.timezone
Or you can set the timezone of your DateTime object:
http://php.net/manual/en/datetime.settimezone.php
Whenever you are converting between dates, you must consider the relevant timezone, as this is the only way for the system to determine how to switch between date formats, make comparisions and output specific dates and times. For example, if you want to convert a date and time to a timestamp, the system must know the timezone of the input date and time so it can convert properly. Take a look at strtotime:
http://us2.php.net/manual/en/function.strtotime.php
Unix timestamps are GMT timezone, so make sure you convert your datetimes accordingly. HTH.

Format Unix Timestamp with Timezone?

Lets say I've got my Unix Timestamp of 1373623247. Now I understand that the timestamps are just seconds since X. The issue I have is the formatting of it.
The server I use is hosted in Germany, however I am in the UK so the output is 12-07-13 12:01:01, when actually its only 11:01:01 here.
The code I am using is as below:
$date = 1373623247;
echo date("j-m-y h:i:s",$date);
What I did was use date_create and timezone as follows:
$date1 = date("j-m-y h:i:s",$date);
$dateobj = date_create("$date1", timezone_open('Europe/London'));
echo date_format($dateobj,"j-m-y h:i:s") . "\n";
The issue I now have is that it's actually adjusted the date to tomorrow, and hasn't altered the time!
You do not need to involve date at all:
$date = 1373623247;
$dateobj = date_create_from_format("U", $date);
date_timezone_set($dateobj, timezone_open('Europe/London'));
echo date_format($dateobj,"j-m-y h:i:s") . "\n";
This code converts the timestamp directly to a DateTime instance using the U format specifier. It's both shorter and cleaner to not work with date, as you don't need to worry about the server's default timezone at all.
Pro tip: date and strtotime get much coverage, and in certain cases are very convenient, but DateTime can do everything on its own and IMHO results in code that is much more maintainable.

Categories