68

I had this construction error when trying to creating a new DateTime object using a timestamp:

Exception: DateTime::_construct(): Failed to parse time string (1372622987) at position 8 (8): Unexpected character in DateTime->_construct()

The object creation code is:

$start_date = new DateTime( "@{$dbResult->db_timestamp}" );

Where $dbResult->db_timestamp is a valid unix timestamp taken from a database. The timestamp in question was:

1372622987

I would understand this error for invalid formats being passed, but this is a genuine timestamp.

The reason this is very strange: I since ran a script to create a new DateTime object with the timestamp passed in as a hard coded value, and it reported no errors.

This seems to have been a one off, but I need an explanation if there is one, as I can't afford for this to happen again.

5
  • Your code seems to work: codepad.org/3RxtyU4b Commented Jul 2, 2013 at 14:04
  • The error you have posted and the code you have posted do not match. The error indicates that the timestamp being passed to the DateTime constructor doesn't have a leading @ on it, while the code you posted shows that it is included. One of those things is inaccurate. Commented Jul 2, 2013 at 14:05
  • @SeanBright I can confirm that removing the leading @ produces this exact error: codepad.org/ZPZmXi2x Commented Jul 2, 2013 at 14:06
  • This is very interesting. I can assure that the @ has always been in the code, and as I said, it works at all times except this occurrence. I wonder if it wasn't interpreted as a one off. Do we know of any problems of using {} notation instead of joining them with '.' notation? Commented Jul 2, 2013 at 14:19
  • I bet that your database result was null. Commented Aug 17, 2015 at 14:03

6 Answers 6

100

You should use setTimestamp instead, if you hardcode it:

$start_date = new DateTime();
$start_date->setTimestamp(1372622987);

in your case

$start_date = new DateTime();
$start_date->setTimestamp($dbResult->db_timestamp);
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for your input. The strange thing is my code has worked before and since, it was just a random occurrence..
I always try to use the proper methods instead of magic strings. I know that the @ and U can work if properly used, but they require additional parsing by the php processor and if there is a method to set the timestamp, using an integer, then you gain a few microseconds in the process.
This is too procedural. This answer is not object orientated. OOP uses constructors. There is a constructor available, so use it. Abani Meher's answer is better, I think.
I would agree with you if the DateTime was immutable and if there was a constructor that accepted a timestamp. For me, a solution that clearly defines an interface setTimestamp(int) is preferable to a solution that does accept a magic string, not to mention the performance issues involved.
Okay, why this works? I had the exact same issue as the OP, and when I used your solution it worked, why?
19

Use the createFromFormat method:

$start_date = DateTime::createFromFormat("U", $dbResult->db_timestamp);

UPDATE

I now recommend the use of Carbon

2 Comments

No worries, be sure to check $start_date for validity before using.
.. that is: $start_date === false (rather than null), since createFromFormat (from what I know) never throws exceptions when failing.
15

change your code to this

$start_date = new DateTime( "@" . $dbResult->db_timestamp );

and it will work fine

4 Comments

That's effectively the same thing isn't it?
@crush - looks same but you can try and see the difference
The @ symbol makes all the diference. See php.net/manual/en/datetime.formats.compound.php and see the "Unix Timestamp" entry
The code has worked as it is, it just failed this once - so hard to pin it down to this
1

This worked for me.

   /**
     * return date in specific format, given a timestamp.
     *
     * @param  timestamp  $datetime
     * @return string
     */
    public static function showDateString($timestamp)
    {
      if ($timestamp !== NULL) {
        $date = new DateTime();
        $date->setTimestamp(intval($timestamp));
        return $date->format("d-m-Y");
      }
      return '';
    }

Comments

0
$start_date = new DateTime();
$start_date->setTimestamp($dbResult->db_timestamp);

Comments

0

you can use Carbon Method for this. This solution also works for Excel Import using csv file.

Carbon::createFromFormat('d/m/Y', $row['scheduled_start_at'])->format('Y-m-d') 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.