Problem/Motivation

When incorrect data is passed as the first argument to format_date(), warnings result.

Per #20 and #32, the issue here is not with the format_date() code but with incorrect arguments passed in. The code documentation for the first argument is clear enough:

$timestamp: A UNIX timestamp to format.

So it's expected that there are warnings or errors when invalid data is passed in.

And format_date() is not unusual in this regard. There are various other core functions that also accept a UNIX timestamp arguments, such as user_pass_rehash(), or as values in associative array arguments, such as user_mail_tokens().

The main problem seems to be the warning occurs at different points in the function and so is confusing for developers who don't immediately understand where the error originates. Can we address that?

One way could be through typehinting the first argument. But (a) a UNIX timestamp is not a PHP data type, (b) PHP 5 doesn't support integer typehinting, and (c) per #20, "integer-like strings" seem to be supported, and enforcing an integer would break backward compatibility.

So this is "won't fix".

Original report by Kartagis

Hi,

I have a development site, where I edit a node, click the devel tab and then token node, and I immediately get the following errors:

Warning: date_timezone_set() expects parameter 1 to be DateTime, boolean given in format_date() (line 2006 of /var/www/drupal7/includes/common.inc).
Warning: date_format() expects parameter 1 to be DateTime, boolean given in format_date() (line 2016 of /var/www/drupal7/includes/common.inc).

Regards,

Comments

bisonbleu’s picture

Same problem. The errors appear when I use the format_date() function inside a subtheme preprocess function.

  function mytheme_preprocess_node(&$vars, $hook) {
    $node = $vars['node'];
    $dc_file_items = field_get_items('node', $node, 'field_dc_file');
    $vars['size'] = format_size($dc_file_items[0]['filesize']);
    $vars['timestamp'] = format_date($dc_file_items[0]['timestamp'], 'custom', 'd M, Y');
  }

The errors disappear when I remove format_date(). But a unix timestamp is not very friendly.

bisonbleu’s picture

After searching in many directions (including installing the Date module - not required), I came to realize that $dc_file_items[0]['timestamp'] was returning a string and not the required integer. Adding intval() around it made the errors disappear. Is this proper? In the end, the last line of the function in #1 should look like this.

$vars['timestamp'] = format_date(intval($dc_file_items[0]['timestamp']), 'custom', 'd M, Y');

Hope this helps.

jasonsafro’s picture

Issue summary: View changes

I had the same issue with 7.30. The warning only showed when I checked pages as the anonymous user. I went into the "users" table and edited the anonymous user record (UID 0). I set the anon user's timezone and the warning stopped showing up.

edvanleeuwen’s picture

Version: 7.18 » 7.36
Component: other » database system

The same error came up with 7.36. The solution mentioned by jacen6678 did the trick.

matroschker’s picture

Version: 7.36 » 7.37

Could reproduce this error on Drupal 7.37 too

diriy’s picture

Version: 7.37 » 7.41
Issue tags: +Commerce Billy, +email adress pdf commerce billy

I have the same while using Billy PDF for produce my PDF file...

vlad.dancer’s picture

Same issue for me while trying drush pmi --format=list

sir_gon’s picture

This issue still persists in 7.43

Casting first parameter like:

        format_date( (int) $timestamp );

works...

bhide.nishad’s picture

Assigned: Unassigned » bhide.nishad
scuba_fly’s picture

Version: 7.41 » 7.43

This is still in version 7.43
I've tried #3 but that does not solve it.
I'm still getting the warnings in my log files after setting the user 0 timezone.

nehapandya55’s picture

Hi,

I also got same issue but #2 works for me.

bhide.nishad’s picture

Assigned: bhide.nishad » Unassigned
Status: Active » Needs review
StatusFileSize
new841 bytes

converting $timestamp into int works for me.
Attaching the patch for the same.

scuba_fly’s picture

When the format_date function is called with a $timestamp value of NULL casting this to a integer value will result in a $date_time object with a value of '1970-01-01 00:00:00' instead of FALSE

If this is the expected behaviour then #12 works.

Included is a screenshot of php storm where I put a breakpoint on in common.inc on the $date_time line 2051.
Also replaced $timestamp with NULL to test this.
common.inc screenshot

Patil_kunal27’s picture

Bellow will fix the issue, but before that we need to add 1 extra condition to check whether it is not NULL nor Blank

$vars['timestamp'] = format_date(intval($dc_file_items[0]['timestamp']), 'custom', 'd M, Y');
OR
$vars['timestamp'] = format_date(int()$dc_file_items[0]['timestamp'], 'custom', 'd M, Y');

Patil_kunal27’s picture

Added extra condition to check whether it is not NULL nor Blank and convert time-stamp to integer

GeorgeWL’s picture

#15 worked perfectly for me, didn't try any of the other solutions.

kartagis’s picture

#12 seems to have worked for me.

fabianx’s picture

Version: 7.43 » 7.x-dev
Assigned: Unassigned » David_Rothstein
Status: Needs review » Needs work
Issue tags: +Needs tests, +Test if present in D8
  1. +++ b/includes/common.inc
    @@ -2048,7 +2048,11 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
    +  if($timestamp != NULL && !empty($timestamp)){
    

    nit - code style violation

  2. +++ b/includes/common.inc
    @@ -2048,7 +2048,11 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
    +	$date_time = date_create('@' . intval($timestamp));
    ...
    +	$date_time = date_create('@' . time());
    

    nit - we use spaces instead of tabs.

We definitely also should document the new behavior for format_date in the function documentation. Especially for the fallback of using the current time for a NULL argument.

Hm, though I am not sure we can do that as it is a BC breaking change. Not sure why someone would need the "0" timestamp though ...

Assigning to David to get some feedback on BC vs. no-BC here.

Oh and it would be great to have at least some unit tests for that.

And we need still check if this is a problem in D8.

David_Rothstein’s picture

Assigned: David_Rothstein » Unassigned

I'm not sure I see the rationale for making format_date() fall back on the current time when nothing is passed in. It doesn't seem related to this issue, plus isn't it a lot more clear (and very simple) for the calling code to handle that? format_date(time()) is easier to read and understand than format_date() with a magic fallback. Plus, in Drupal there is ambiguity about what is meant by the "current time" (it could be time() or it could be REQUEST_TIME) so I think it's better for the calling code to decide exactly what they want.

I don't see any reason the patch should change the current function behavior when something unexpected (like NULL) is passed in at all... if we need to convert to an integer, shouldn't that only happen when an integer-like timestamp is passed in? The patch is actually confusing me a bit. It does this:

-  $date_time = date_create('@' . $timestamp);
....
+	$date_time = date_create('@' . intval($timestamp));

But if $timestamp is a string, we are concatenating it into a string at the end anyway, so what advantage is there to converting it to an integer first and then back to a string again? I wonder if this patch is actually just hiding situations where bad input was sent to the function...

David_Rothstein’s picture

I just did a quick test and found that passing in a string as the $timestamp to format_date() actually works fine already, as long as the string "looks like" an actual integer timestamp. In other words, both of these are equivalent:

$ drush php-eval 'print format_date(1234567890)."\n"'
Fri, 02/13/2009 - 18:31
$ drush php-eval 'print format_date("1234567890")."\n"'
Fri, 02/13/2009 - 18:31

So I'm not sure this patch is necessary. If you pass in something that isn't integer-like, it fails regardless of whether it's an integer or string, i.e. all these produce the date_timezone_set() warning:

$ drush php-eval 'print format_date(1234567890.5)."\n"'
$ drush php-eval 'print format_date("1234567890.5")."\n"'
$ drush php-eval 'print format_date("something")."\n"'

However, that seems expected to me. (I guess you could argue that Drupal could try to return something sensible for the first two, but it would not be precise...)

So unless someone can show an example where this function is failing and it's not the fault of the calling code, I think we should consider just updating the documentation here (to clarify that only integers or integer-like strings are supposed to be passed in).

cj-a-min’s picture

Same error is thrown for using non unix timestamp. 'Warning: date_timezone_set() expects parameter 1 to be DateTime, boolean given'

For some people that come across this thread, it might be, they are pulling dates from a date module field or other type date field so they are stored in db like, 2016-08-22 00:00:00.

format_date expects timestamp.

$timestamp = strtotime($field_some_date_field);
$mydate = format_date($timestamp, 'custom', 'Y');
print $mydate;

2016

scottsawyer’s picture

I am getting this error when I attempt to add load a VBO view to a Rules action. I checked both issue queues, I can't find anyone else having this issue.

For me, a simple view of any entity, users, nodes, etc, add a VBO field, in my case, I am loading 1 user. Then create a simple rule, add an action, load entities ( or entity ids ) from a VBO view. I immediately receive the following:

Warning: date_timezone_set() expects parameter 1 to be DateTime, boolean given in format_date() (line 2062 of /var/www/drupal/public/includes/common.inc).
Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in format_date() (line 2072 of /var/www/drupal/public/includes/common.inc).
Warning: date_timezone_set() expects parameter 1 to be DateTime, boolean given in format_date() (line 2062 of /var/www/drupal/public/includes/common.inc).
Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in format_date() (line 2072 of /var/www/drupal/public/includes/common.inc).

Other places where I have dates work correctly, fields, timezones, etc. I am not even sure what is calling date_timezone_set, or date_format in this case.

nellngun’s picture

Patch works for line 2040, 2050 of /var/www/drupal7/includes/common.inc) too!

scott.browne’s picture

#15 works perfectly. Thank you!

gorkagr’s picture

Hi!

I confirm that the patch in #15 works as well for me, but for 7.64, I submit a new patch as the location of the lines in the file has changed

Best,

damienmckenna’s picture

Version: 7.64 » 7.x-dev
damienmckenna’s picture

The patch in #25 needs to be updated to match Drupal's coding standards, specifically the "else" statement is expected to be on a separate line.

gorkagr’s picture

StatusFileSize
new634 bytes

Here it is, with drupal standards

indigoxela’s picture

Just realized, this problem beats me in rare cases...

UPDATE: it turned out, my problem was something totally unrelated. Sorry for the noise.

Removed pointless comment.

indigoxela’s picture

Removed pointless comment.

jenlampton’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new629 bytes

The patch in #28 worked for me. Rerolled here to remove the whitespace at the end of one line.

jamesoakley’s picture

I notice nobody picked up David's comment in #20

So unless someone can show an example where this function is failing and it's not the fault of the calling code, I think we should consider just updating the documentation here (to clarify that only integers or integer-like strings are supposed to be passed in).

loopy1492’s picture

We're performing a PHP 8 upgrade and came across this error.

Here's a trimmed-down version of the code throwing the error:

foreach ($node->field_content_to_pull_in_na['und'] as $referenced) {
  $date = $referenced['entity']->created;
}
print format_date($date, 'custom', 'F j, Y');

The patch stopped the error.

I did try wrapping the print statement with if (isset($date)), but that seemed to do nothing.

I also tried transforming $date with strtotime() both at variable assignment and at the format_date function and that did nothing as well.

nedjo’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Closed (won't fix)

Per #20 and #32, the issue here is not with the format_date() code but with incorrect arguments passed in. The code documentation for the first argument is clear enough:

$timestamp: A UNIX timestamp to format.

So it's expected that there are warnings or errors when invalid data is passed in.

And format_date() is not unusual in this regard. There are various other core functions that also accept a UNIX timestamp arguments, such as user_pass_rehash(), or as values in associative array arguments, such as user_mail_tokens().

The main problem seems to be the warning occurs at different points in the function and so is confusing for developers who don't immediately understand where the error originates. Can we address that?

One way could be through typehinting the first argument. But (a) a UNIX timestamp is not a PHP data type, (b) PHP 5 doesn't support integer typehinting, and (c) per #20, "integer-like strings" seem to be supported, and enforcing an integer would break backward compatibility.

So this is "won't fix".

quietone’s picture

Issue tags: -, -, -Test if present in D8