strtotime converting on wrong timezone - php

I am facing the following problem when converting a date value using strtotime().
If I do: strtotime('1/1/2019') the output would be 1546293600 -> 31.12.2018 # 10:00pm (UTC)
If I do: date_default_timezone_get() the output is Europe/Bucharest
In my php.ini file (of my hosting account), the timezone is set to date.timezone="Europe/Helsinki"
I have following two questions.
Shouldn't date_default_timezone_get() output what it is configured
in my hosting accounts php.ini file? (the
date_default_timezone_set() is not being used)?
Why the strtotime() conversion result is on GMT-2 timezone? It is
my understanding that if there is no timestamp supplied, the
conversion should be done on the current time (which should be
GMT+2, either Helsinki or Bucharest)?
If I do date_default_timezone_set('UTC') the conversion result of strtotime('1/1/2019) is done correctly (on GMT+2).
Thank you.

There may be some reasons why this is happening and we can't tell you why, because we don't know your application, since it may somewhere change the time zone at runtime.
Instead you should stop using strtotime and embrace object oriented DateTime functions.
Using DateTime you can define your date along with its time zone:
// local time
$date = new \DateTimeImmutable('1/1/2019', new \DateTimeZone('Europe/Bucharest'));
echo $date->format('U > d.m.Y (e)') , '<br>';
// convert to UTC
echo $date->setTimeZone(new \DateTimeZone('UTC'))->format('U > d.m.Y (e)');
The library is quite powerful and much more verbose than operating on strings and unix timestamps.

Provide hour and timezone to the function using the full IS0 8601 format 2019-01-01T12:00:00+00:00. That way you will get the correct timestamp in UTC. If you won't use the hour I recommend to use 12 AM.
In the following example I will use a numeric date array to build this string
// [Y,m,d]
$date = [2019,1,1];
for($i=1; $i<3; $i++){
$date[$i] = str_pad($date[$i],2,'0',STR_PAD_LEFT);
}
$t1 = strtotime(implode('-',$date).'T12:00:00+00:00');
echo date('r',$t1);
//=>Tue, 01 Jan 2019 12:00:00 +0000

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

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.

Converting from EDT to GMT+05.30 time zone in php for entering timestamp in mysql database

My php web servers timezone is EDT (Eastern Day Light Time (US)). My current timezone is GMT+05.30. I need to enter current timestamp into my mysql database with the timestamp in my current timezone. By the way, I'm using a free php web server for my use. So I will not be having any previleges for modifying the server. Can some one suggest me some way of converting it to my GMT+05.30 from EDT in php using any script.Thanks in advance.
Have a look at the following example
$timezone = new DateTimeZone('Europe/Berlin');
$date = new DateTime('#' . $yourTimestamp, $timezone);
echo $date->format('c');
So through the DateTimeZone Object your Time will be formatted by the DateTime object.
I suggest you use the date_default_timezone PHP function.
You can read about it here and here is the list of Supported Timezones
Example:
<?php
date_default_timezone_set('Europe/Amsterdam');
?>
Use this:
echo gmdate("Y:F:l h:i:s",time()+19800);

How to deal with Date and Timezone in PHP with AWS API

I'm using the AWS PHP SDK and Amazon's API is returning this timestamp below.
2013-04-23T13:18:00Z
The timestamp they are giving me seems to be in my timezone already. Since it doesn't specify which timezone it is, I guess it's assumed to be my local time. The wiki site for ISO 8601 also states...
If no UTC relation information is given with a time representation, the time is assumed to be in local time.
But when I try to use it in PHP like this it is converting it into my local timezone. PHP's strtotime page says this...
Each parameter of this function uses the default time zone unless a time zone is specified in that parameter.
My question is why is strtotime converting it into my timezone if it's already in my timezone?
The "Z" at the end of the date returned by Amazon means it's UTC. You will need to convert the timezone to have it be localized. You can do this by doing the following:
<?php
$date = new DateTime('2013-04-23T13:18:00Z'); // Z = UTC
echo $date->format('H') . PHP_EOL;
//> 13
$date->setTimezone(new DateTimeZone('America/Los_Angeles')); // -0700
echo $date->format('H') . PHP_EOL;
//> 06
Update: Read all the comments for the full solution.

Getting timestamp from relative date/time string with specific timezone AND specific $now value

I'm aware of two ways to get a timestamp from a relative date/time string in PHP:
strtotime: Allows user to specify their own $now value
DateTime object: Allows user to specify their own $timezone value
Is there a way to get a timestamp from a date/time string that allows one to specify both the timezone AND the $now value? It seems like the only way would be to use strtotime while temporarily overriding the default timezone for the entire php application and then setting it back immediately afterwards. That just seems like a hacky solution, and it would be nice if there were a cleaner way.
Edit: there seems to be some misunderstanding about what I'm trying to do. Here's a more concrete example:
"I want to find the timestamp corresponding to the string 'next tuesday at 3:00pm' within the America/Los_Angeles timezone AND specifying an arbitrary value for $now, such as March 14th, 2014 at 8:05am."
I've prepared an example. This may be want you want:
<?php
// Including the timezone int the time strings (thanks #Mike B!!!)
// will make it very easy. just strtotime() is required
// create a timestamp for March 14th PDT
$now = strtotime('14 March 2014 8:05am America/Los_Angeles');
// get the requested timestamp.
$nexTuesday = strtotime('next tuesday 3:00 pm America/Los_Angeles', $now);

Categories