Fatal error: Call to a member function format() on boolean passing in WordPress ACF Datepicker to template

Here is my code:

$original_date = get_field('event_date');
$date = DateTime::createFromFormat('lFdY', strtotime($original_date));
$new_date = $date->format('l, F d, Y');

This code is in a custom post loop in a shortcode and called in the WordPress admin.

Read More

I have also tried it without the strtotime. I am using PHP 5.6.
The event_date field is from an Advance Custom Fields date picker.

If I just pass the field, I get my intended output (the input from the custom post admin page), but without whitespace and commas. I also set this, save and display values in the acf in WP.

This is the error:

Fatal error: Call to a member function format() on boolean on the line
with $new_date variable.

Then if I use:

$date = date("l, F d, Y", strtotime($original_date));

The loop throws an error, undefined variable, for each instance of the post.

Related posts

4 comments

  1. You should pass the string directly to the createFromFormat method:

    $date = DateTime::createFromFormat('lFdY', $original_date);
    

    The boolean you’re receiving is because createFromFormat is failing and returning false.

    If you’re still receiving an error, get_field() is likely not returning what you think it is.

  2. Try using this .. <?php echo date('l, F d, Y', strtotime(get_field('event_date')));?> it is working at my end

    Make sure your get_field('event_date') returns you the date in 20160113 format If not then change the return format from ACF setting in WP back-end.

    enter image description here

  3. DateTime::createFromFormat returns false if it fails to convert the input string using the format specified.

    In your case, you’re taking an $original_date, converting it to a numeric timestamp, and trying to pass that in to DateTime::createFromFormat, which isn’t going to work, hence the error. You’ll need to pass in the original date instead:

    $date = DateTime::createFromFormat('lFdY', $original_date);
    

    PHP currently can not parse that specific format string. You can demonstrate this with an easy case that should “obviously” work. This:

    DateTime::createFromFormat('lFdY', date('lFdY', time()));
    

    returns false. The issue is specifically because of the lack of space between l and F in the format string and between the day-of-week and month in your input string.

    You should use a different date format. If you can remove the text representation of the day-of-week (because it’s not actually necessary to disambiguate the date), or at least get a space between the day-of-week and the month, that would be best.

    Since you have existing data in your database in an unhelpful format, you could write a relatively simple pre-processor to remove the day-of-week from the input string:

    $new_date = substr($original_date, strpos($original_date, 'y') + 1);
    $date = DateTime::createFromFormat('FdY', $new_date);
    

    (This example assumes always english day names, in lowercase, and the input is always valid. You may need more complicated code for your actual data.)

    Nitty, gritty details: When PHP processes the l formatter (day of week), it requires seeing one of the characters in: ,;:/.-(), a space, tab, or end-of-string as an indication of where to stop reading.

    So, if your date string is FridayJuly082016, because there are no spaces whatsoever in the input date, the code continues reading the entire string, and then fails because (literally) FridayJuly082016 is not in the list of days of the week.

    Unfortunately for your particular case, this is also not likely to be “fixed”. You have an extremely unusual date format, and making this particular case work in the code would make it considerably more complicated, for a questionable and rare use case.

  4. @jbafford I found a solution.
    First I save the date format to yymmdd in the ACF datepicker field

    Then I used this code to extract the year month and date separately and then formatted the strtotime result:

    $odate = get_field('event_date');
    $y = substr($odate, 0, 4); $m = substr($odate, 4, 2); $d = substr($odate, 6, 2);
    
    $new_date = date('l, F j, Y', strtotime("{$d}-{$m}-{$y}"));
    

    What confused me I think and got me hung up was the presumption that I had to pass l or the day into the strtotime and that I had to match input with the intended formatted output. PHP date doesn’t need that much info to accomplish the task. Thanks for all of your input!

Comments are closed.