27

I'm using the jquery daterangepicker, which in turn uses the jQuery datapicker.

My Ubuntu system works fine. The browser is sending a parseable string:

$dateStarted = new \DateTime($post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (MST) print_r($dateStarted); 

Outputs:

DateTime Object ( [date] => 2012-11-15 00:00:00 [timezone_type] => 1 [timezone] => -07:00 ) 

On our testers Windows system, the browser is sending an expanded timezone in the string:

$dateStarted = new \DateTime($post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time) print_r($dateStarted); 

Throws and exception:

Exception: DateTime::__construct(): Failed to parse time string (Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time)) at position 41 (i): Double timezone specification 

I've googled around and can't find any resources on this specific PHP error.

I'm "solving" this problem by striping out the bracketed text which returns the same results:

$dateString = strstr($dateString, " (", true); // Thu Nov 15 2012 00:00:00 GMT-0700 

This seems pretty bad to do and I'm looking for suggestions on how to do this properly.

2
  • 1
    try ->createfromformat() instead, and make one of those two timezones "noise" so the parser ignores it. you get the warning because it's possible to get a TZ conflict (e.g. badly build string that says GMT +0800 (EDT).) Commented Nov 16, 2012 at 17:40
  • The bootstrap datepicker ( github.com/eternicode/bootstrap-datepicker ) I believe, uses the same basis. Turns out that when you ask the selected date, it will return a javascript Date object. You can have this object return a UTC string that will always be the same format across browsers and is parsable by new \DateTime. Do it like this: `var dateString = yourDate.toUTCString();' Commented Oct 13, 2015 at 8:09

3 Answers 3

30

Using DateTime::createFromFormat() as Marc B suggested seems to be a better solution.

What I've ended up with is:

$dateStarted = \DateTime::createFromFormat('D M d Y H:i:s e+', $post['startDate']); // Thu Nov 15 2012 00:00:00 GMT-0700 (Mountain Standard Time) print_r($dateStarted); print_r(\DateTime::getLastErrors()); 

Which outputs the correct date now:

DateTime Object ( [date] => 2012-11-15 00:00:00 [timezone_type] => 1 [timezone] => -07:00 ) Array ( [warning_count] => 1 [warnings] => Array ( [33] => Trailing data ) [error_count] => 0 [errors] => Array ( ) ) 

The + at the end of the format is the magic that makes this work.

Sign up to request clarification or add additional context in comments.

2 Comments

@OlafDietsche Thanks! There's one caveat. This works on PHP 5.3.10 and not on 5.3.2. I suspect that the + operator has a bug that's been fixed.
@imperium2335 its right there in the docs: If this format specifier is present, trailing data in the string will not cause an error, but a warning instead
7

I would say this is a bug. You get the same error, when using this string

$dateStarted = new \DateTime("Thu Nov 15 2012 00:00:00 GMT-0700 (abcdefg)"); 

One less

$dateStarted = new \DateTime("Thu Nov 15 2012 00:00:00 GMT-0700 (abcdef)"); 

and it is parsed "properly".

It seems the time zone string is restricted to 6 characters. Unless you can and are willing to configure your Windows clients, I would say stripping the "time zone" is a viable "solution".

1 Comment

It's 2018 and the issue still persists. For what it's worth, you may clip the date string to length 33. Excludes all garbage, and works like a charm.
0

I'm working in php 7.2 with laravel 5.6. Most upvoted unswer is not working since that method is not found in this php version. (I'm not sure, but it gives an error saying that method not found). But instead there is a method which behaves exactly the same as that which solves the original issue (Converting a javascript date object to timestamp).

$fromDate = date_create_from_format('D M d Y H:i:s e+', $fromDate); 

This can then be used in db queries or as a date object.

2 Comments

your answer is just a procedural method of the accepted answer.
Yes true. But I thought of adding this here since it helped me where it complained with the previous. I think that answer is edited later.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.