Using strtotime and taking timezone into consideration - php

I have a system running in PHP and am using CodeIgniter (if there is a CI specific answer to this I would be happy as well).
I often need to figure out the timestamp of dates such as "this Thursday" or "this Monday". I currently use strtotime("this Thursday") and it gives me what I ask for.
I have a server in EST. It is 01:00 (1:00am), early morning Friday, Feb 24, 2012 in New York.
I have a user who has specified his timezone to be Pacific time. Right now it is 22:00 (10pm) late evening Thursday Feb 23, 2012 in San Francisco.
I use strtotime("this Thursday"). Since my server is in EST, it returns me the timestamp for March 1, 2012. I would like to take the user's timezone into consideration. For my user, "this Thursday" should return Feb 23, 2012.
Can I use strtotime("this Thursday") for it, and if so, how would I specify the target timezone?
If not, what approach would you suggest to getting the date for "this Thursday" in a specific timezone.

The manual for strtotime links directly to date_default_timezone_set. I would take that as a hint to use that.

I just figured out that strtotime takes a $now parameter. I can specify the $now param to be the current time in the user's timezone and strtotime returns me what I need.

This is taken string from the php site
<?php
date_default_timezone_set('Asia/Shanghai');
$first_day_of_month = date('Y-m',time()) . '-01 00:00:01';
$t = strtotime($first_day_of_month);
print_r(array(
date('Y-m',$t),
date('Y-m',strtotime('- 1 month',$t)),
date('Y-m',strtotime('- 2 month',$t)),
));
?>

Related

Using strtotime() PHP and revert back trough gmdate() is not returning same date

I have a string $StartDate = "2015-09-23" (should be like yyyy-mm-dd).
Than I make $UdtStart= strtotime($StartDate) that returns 1442980800;
Well if I go to this link it return back "Wed, 23 Sep 2015 04:00:00 +0000".
First, why do we have 04:00:00 added?
Than, if I do this $back=gmdate("Y-m-d H:i:s", ($UdtStart)); I will have "2015-09-26 04:00:00".
What am I missing?
$UdtStart= strtotime($StartDate);
$back=gmdate("Y-m-d H:i:s", ($UdtStart));
Wed, 23 Sep 2015 04:00:00 +0000
Note that +0000 on the end, that means the time is UTC. As per the PHP strtotime() doco:
Each parameter of this function uses the default time zone unless a time zone is specified in that parameter.
The gmdate is for Greenwich Mean Time (and really should be called something like utcdate nowadays), so you're asking for the data in a different foramt from what you gave it.
I'd be willing to bet money that you're in a timezone four hours removed from UTC, which is why you're seeing that.
If you want local time, use date() rather than gmdate(). The gmdate doco states:
Identical to the date() function except that the time returned is Greenwich Mean Time (GMT).

PHP IntlDateFormatter::parse Output Timezone

I have the following PHP code:
$date = 'janvier 1, 2014 à 5:00PM';
$formatter = new IntlDateFormatter('fr_CA', IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/Toronto', IntlDateFormatter::GREGORIAN, 'MMMM d, yyyy 'à' h:mma');
$date = $formatter->parse($date);
var_dump($date);
The output is:
int(1388613600)
This appears to be a UNIX timestamp, which is always UTC, Right? So it's automatically being converted from America/Toronto?
Just confirming that I have this correct. I don't have a lot of experience with PHP and time zones, so I appreciate any help.
Correct. The timestamp is a UNIX timestamp. That is - the number of whole seconds since Jan 1, 1970 UTC, not accounting for leap seconds.
You can verify the timestamp using a site like epochconverter.com
1388613600 = 2014-01-01T22:00:00Z
Then you can check the time zone details at timeanddate.com.
In January 2014, Toronto was on EST, which is UTC-05:00.
This calculation clearly verifies that 22:00 UTC is 5:00 PM EST.
As Marc B mentioned, date('r', 1388613600) returned a formatted version of the date including the timezone offset which was set to +0000.
The output is in fact UTC.
Thanks Marc!

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);

PHP strtotime for June returns July

I'm stumped as to why the following PHP strtotime function returns '07' as the month number, rather than '06' when $monthToGet = 'June':
$monthToGet = $_GET['mon'];
$monthAsNumber = date('m', strtotime($monthToGet));
From searching, it appears it may be due to default date parameters (in this case the day and year) as I haven't specified them. Would that be the cause?
Any suggestions appreciated!
TL;DR
You are right
echo date("m", strtotime("June"));
-> 07
However, this does work:
echo date("m", strtotime("1. June 2012"));
-> 06
The problem explained
Today is 31. July 2012 and since you provide only a month, the current day and current year are used to create a valid date.
See the documentation:
NOTE
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
Alternatives
You could use date_parse_from_format() or strptime() to achieve what you want with a slightly different approach.
(Thanks to johannes_ and johann__ for their input)
Fixed with :
$monthToGet = '1 '. $_GET['mon'];
But I still don't get why, since "m" is a valid date format
Today is 31 Jul. So a strtotime with only "June" is interpreted as 31 June => 1 July.
In fact:
echo date("Y-m-d",strtotime("January")); // 2012-01-31
echo date("Y-m-d",strtotime("February")); // 2012-03-02
of course... only today 31 Jul 2012 :) Tomorrow all will works.
You're lucky because you found this bug just today ;)

PHP Date / GMT Weirdness

Either I'm losing my mind, or I've not got the faintest idea what I'm doing. I'm leaning towards the latter.
I'm trying to convert this: 1316826000, which I'm pretty confident should be Sat, 24 Sep 2011 01:00:00 GMT
http://www.onlineconversion.com/unix_time.htm confirms this.
http://www.unixtimestamp.com/index.php tells me 09 / 23 / 11 # 8:00:00pm EST, so far so good. I happen to be in EST, this is the result I'd like to get back from PHP.
When I do date('l, M d, Y, h:ia', $iTime), I get: Friday, Sep 23, 2011, 12:00am, a full 20 hours off.
I've confirmed the server's time is correct using date('c'). date('c') output is: 2012-05-19T03:19:20+00:00. The server is in the central time zone, where it is currently 10:20pm. May 18.
echo date_default_timezone_get() outputs "GMT" (set somewhere else in the script using date_default_timezone_set('GMT'))
What am I missing? Nothing I've read so far can explain how I'm getting a result 20 hours behind what it should be. Were it an hour fast or slow, I could at least wrap my head around it being some sort of DST idiotry, but 20? Crazyness! Thanks for reading!
Check what your php.ini says for date.timezone.
In unix it is usually here: /etc/php.ini
Then use a proper timezone recognized by PHP:
http://www.php.net/manual/en/timezones.php
date.timezone = 'America/New_York'
Then reload your web server.
Unix time just means the number of seconds since epoch. Has nothing to do with timezones. Timezones simply add or subtract 1 hour (3600 seconds) from the unix time for each zone you move away from GMT.
An example:
$userTimezone = new DateTimeZone('America/New_York');
$gmtTimezone = new DateTimeZone('GMT');
$myDateTime = new DateTime('2014-01-22 11:44', $gmtTimezone);
$offset = $userTimezone->getOffset($myDateTime);
echo $offset;
That will output: -14400 or 4 hours. Which is the difference between New York and GMT
Using some Java code with the Joda-Time 2.3 library, as I don't know PHP…
long m = 1316826000L;
DateTime dateTimeUtc = new DateTime( m * 1000L, DateTimeZone.UTC );
DateTime dateTimeNewYork = dateTimeUtc.toDateTime( DateTimeZone.forID( "America/New_York" ) );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeNewYork: " + dateTimeNewYork );
I can tell you that 1316826000 seconds from the beginning of 1970 UTC/GMT (Unix Epoch) is…
dateTimeUtc: 2011-09-24T01:00:00.000Z
dateTimeNewYork: 2011-09-23T21:00:00.000-04:00
So, as the commenter stated, it would be 8 PM in EST but EST was not in effect on that day. DST (Daylight Saving Time) (idiocy, as you correctly noted) was in effect until November 9 of that year (2011). So the time of day is pushed forward one hour, to 9 PM.
In GMT/UTC, that means 1 AM in the morning of the next day.
Standard time in east coast US is 5 hours behind UTC/GMT. With DST it is 4 hours behind UTC/GMT (one hour closer).
Where you got confused:
Your time format/conversion in incorrect.I can't help with that as I don't know PHP.
You should be using a competent date-time library for this kind of work.Date-time work is complicated, tricky, confusing, and error-prone.This question discusses possibilities of Joda-Time (for Java) sorts of libraries for PHP.
You used three-letter time zone codes. Avoid these.Those codes are neither standardized nor unique -- there are common duplicates. Instead, use proper time zone names. In your case of east coast US, "America/New_York". Furthermore, in this case you confused the time zone area and rules (east coast US) with a particular application of those rules (EST). Saying "America/New_York" means "whatever time zone rules were in effect on that date, whereas saying "EST" (if interpreted to mean Eastern Standard Time in US) means "UTC-05:00". So either (a) use a time zone name such as "America/New_York", or (b) use a specific offset such as "-05:00".

Categories