I got this error while deleting/editing polls/nodes:
Strict warning: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Chicago' for 'CDT/-5.0/DST' instead in node_validate() (line 846 of /home/davereid/Projects/drupal-head/modules/node/node.module).

Offending lines of code in node.module:

function node_validate($node, $form = array()) {
  ...
    // Validate the "authored on" field. As of PHP 5.1.0, strtotime returns FALSE instead of -1 upon failure.
    if (!empty($node->date) && strtotime($node->date) <= 0) {
      form_set_error('date', t('You have to specify a valid date.'));
    }
  ...
}
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Dave Reid’s picture

Here's at least a start to changing the return value check to strtotime($node->date) === FALSE since we need PHP 5.2 now. Figuring out how to fix the warning. I almost wish that we did something with using Drupal's timezone with date_default_timezone_set() in _drupal_bootstrap_full() so all these strict warnings can be avoided...

Dave Reid’s picture

Status: Active » Needs work

Setting to code needs work...

Damien Tournoud’s picture

There seems to be no timezone-agnostic replacement for strtotime(). So the solution is to set a default timezone as early as possible.

Dave Reid’s picture

Maybe this should do just date_default_timezone_set(date_default_timezone_get())?

This needs re-roll since #279516: Remove workarounds for PHP versions less than 5.2.x was committed before this.

Dave Reid’s picture

Title: PHP strict warning: strtotime() in node_validate() » PHP strict warning: strtotime()

Also changing title since this has narrowed.

Dave Reid’s picture

Title: PHP strict warning: strtotime() » Avoid PHP strict timezone warnings by calling date_default_timezone_set in bootstrap

With the new timezone settings, how is the best way to call date_default_timezone_set()?

mfb’s picture

something like

date_default_timezone_set(variable_get('date_default_timezone', date_default_timezone_get()));

could now be used

Dave Reid’s picture

This is definately needed since the system update for updating user's timezones as a part of #11077: Introduce Daylight Saving Time for Drupal cause a bunch of PHP strict notices:

Strict warning: date_create(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Chicago' for 'CST/-6.0/no DST' instead in format_date() (line 1385 of /home/davereid/Projects/drupal-head/includes/common.inc).

mfb’s picture

I'm pretty sure that drupal_initialize_variables() is called too early for the variable_get() in date_default_timezone_set(variable_get('date_default_timezone', date_default_timezone_get())); to actually get the variable. Can date_default_timezone_set() be called later in bootstrap?

mfb’s picture

Oops, I thought you had tested your suggestion in #4. date_default_timezone_get() also throws strict notices, so it should just be 'UTC' as a default.

jjkd’s picture

The patch from #3 no longer applies cleanly to HEAD, namely the portion of the patch for node.

The patch for bootstrap.inc to use 'UTC' does apply with offset, and does eliminate the strict warnings regarding strtotime() in my testing.

Dave Reid’s picture

Revised patch to use date_default_timezone_set('America/Chicago') instead of 'UTC'. By the way, I have attached a screenshot of the user edit page when strict errors are enabled... it's a big big big explosion.

Dave Reid’s picture

Status: Needs work » Needs review
mfb’s picture

Status: Needs review » Needs work

Can't we have a one-line patch, just calling date_default_timezone_set(variable_get('date_default_timezone', 'UTC')); at some point in bootstrap? Also, UTC is the default in previous versions of Drupal and also in PHP itself, so not sure why you're using America/Chicago.

Dave Reid’s picture

Status: Needs work » Needs review
FileSize
2.25 KB

Ah, I didn't see that 'UTC' was a valid choice in the timezone select option. I had to add an error-ignore to the calls to date_default_timezone_get since they can and will generate PHP strict notices if the date.timezone PHP setting is not set.

mfb’s picture

I'm having a hard time testing this because I'm also seeing other strict warnings like Strict Standards: Declaration of DatabaseConnection_sqlite::prepare() should be compatible with that of PDO::prepare() in /home/d7strict/includes/database/sqlite/database.inc on line 165 Fatal error: Declaration of DatabaseStatementPrefetch::execute() must be compatible with that of DatabaseStatementInterface::execute() in /home/d7strict/includes/database/prefetch.inc on line 23

Presumably I'm not the only person seeing this? maybe we could fix all the other strict warnings in this issue? I think most of them have to do with not providing default values when declaring methods, i.e. public function execute($args, $options) { should be public function execute($args = array(), $options = array()) {

Dave Reid’s picture

That looks like a strict problem the the new sqlite driver. If we were to fix all strict issues in one patch, it would be a kitten-killer. Separate issues should be filed so they can be easily reviewed.

mfb’s picture

FileSize
2.54 KB

I was already seeing other PDO-related strict issues, sqlite is just the latest. personally I don't think it would be too difficult to fix all the strict issues in one patch, but up to you. i'm attaching what I found so far in case you want to incorporate into this or another issue.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
3.58 KB

OK this fixes all the strict issues I found so far. Also, I did not need to add an error-ignore to the calls to date_default_timezone_get() because drupal should always be fully bootstrapped before this function is called.

mfb’s picture

FileSize
3.6 KB

I thought some more about this. With this patch it's rather pointless to call date_default_timezone_get() in various places as a default time zone since this will now always be 'UTC' if it hasn't been otherwise configured in drupal. So if we care about getting the server environment's time zone we should call date_default_timezone_set(variable_get('date_default_timezone', @date_default_timezone_get())) in bootstrap.

Status: Needs review » Needs work

The last submitted patch failed testing.

Dave Reid’s picture

Status: Needs work » Needs review
FileSize
2.28 KB

Type-hinting/strict issue has been moved #318016: Type hint array parameters. Revised patch.

mfb’s picture

Status: Needs review » Needs work

I think my last patch was the right way to do it: date_default_timezone_set(variable_get('date_default_timezone', @date_default_timezone_get())); This allows the server environment's time zone to be applied as the default time zone rather than ignoring it and using UTC.

Also, there should be no reason for the "@" elsewhere on date_default_timezone_get() because it will always have been set during bootstrap.

Dave Reid’s picture

Status: Needs work » Needs review
FileSize
2.3 KB

Here's my argument for #23...the variable 'date_default_timezone' going to be set during the install, which is not at a full bootstrap. We do not want to show the PHP strict error there. I agree we should use date_default_timezone_get() for the DRUPAL_BOOTSTRAP_FULL instead of 'UTC', since it is consistent with the default value for the 'date_default_timezone' variable elsewhere. We still need the '@' since the code will still be called on each full bootstrap, since it is provided as the default value for variable_get(). We should be hiding that PHP strict error.

mfb’s picture

Install does bootstrap during install. So (last I looked at it) default time zone was getting set before hitting the install settings form.

Dave Reid’s picture

mfb, you are right! The only change needed is the one in _drupal_bootstrap_full()! I checked the install and confirmed no more strict timezone errors.

Dave Reid’s picture

Dave Reid’s picture

Revised comment that actually ends in a period now.

mfb’s picture

One little problem is update.php going from d6 to d7. In d6, data_default_timezone is just a number not a valid timezone so this causes a PHP notice like "Timezone ID '10800' is invalid". Easy work-around for this would be putting the "@" in front of date_default_timezone_set().

Status: Needs review » Needs work

The last submitted patch failed testing.

Dave Reid’s picture

Component: node.module » base system
Status: Needs work » Needs review

Testing failure on slave #8.

mfb’s picture

Status: Needs review » Needs work

See #30 re: update.php PHP notice (technically worse than the PHP strict this is fixing)

Dave Reid’s picture

c960657’s picture

Shouldn't the default timezone be set to the current user's timezone (if one exists) instead? strtotime() is used e.g. in node_validate() to parse a date entered by the current user. Since all dates are displayed in the user's local timezone, it seems reasonable for him to assume that he can enter dates in his own timezone as well.

c960657’s picture

Status: Needs work » Needs review
FileSize
8.13 KB

This patch sets PHP's default timezone based on the user's timezone (if one exists).

Dave Reid’s picture

I don't think thats the correct approach. We want all base time operations to be done in the site's timezone format, but any 'display' time operations (like format_time) to be done in the user's timezone. I'd need to look into it though.

Status: Needs review » Needs work

The last submitted patch failed testing.

Dave Reid’s picture

Status: Needs work » Needs review

Bitten by the 'file naming' testing bot failure.

mfb’s picture

Sometimes it makes sense to use the user's time zone, e.g. the strtotime() calls in node and comment modules that c960657 mentioned, but in other cases (mainly in contrib modules) the system time zone is desired. For example, when generating URL path components with the date() function, I usually want the year/month/day to be in the system time zone.

Maybe we could try to figure out which scenario is most common, or if any contrib modules would be really broken by a fluctuating time zone depending on the user. Whichever we make the default time zone, it's not hard to parse or generate dates in any time zone, for example we could make a little utility function to replace strtotime() that uses date_create(), timezone_open(), etc. to work in the user's time zone if user-configured time zones are enabled.

chx’s picture

Wait did we agree on making Drupal compliant with E_STRICT?

c960657’s picture

@chx:
I'm not sure we have reached a conclusion about maing Drupal E_STRICT compliant, but it has been requested in #350543: Use E_STRICT error reporting. This issue is not only about getting rid of the E_STRICT warning, though, but also about making Drupal behave in a consistent and well-defined way independently of the timezone setting in php.ini.

@mfb:
I have no impression of what the common scenario is. format_date() currently uses the user's timezone unless another timezone is explicitly specified. It would improve consistency if PHP's native date functions did this as well. Adding a utility function for parsing dates is probably a good idea (but outside the scope of this issue).

mfb’s picture

@c960657: Here's the resulting changes in contrib modules that I could think of, that might need some documentation:

Token and Pathauto use date() rather than format_date() to create paths so the path is consistent for all users. A work-around for date($format, $timestamp) would be format_date($timestamp, 'custom', $format, variable_get('date_default_timezone', date_default_timezone_get()), 'en').

The Views date argument and filter will now be returning different nodes for different users using the same date value. This could be considered a good thing although it could lead to some confusion.

mfb’s picture

FileSize
4.52 KB

What do you think about this simplified patch. I added a small utility function to avoid code duplication between bootstrap.inc and session.inc.

c960657’s picture

I think it looks good.

If the D6->D7 upgrade is the only case where date_default_timezone_set() is expected to trigger an error, I wonder whether it is better to drop the @ and instead call @date_default_timezone_set(date_default_timezone_get()) at the top of upgrade.php? This will allow the site admin to discover if the timezone variable has somehow become invalid (e.g. an empty string), or if there is a problem with the timezone database (new list of zones is not completely static).

mfb’s picture

FileSize
4.45 KB

@c960657: It looks like when you moved the date_default_timezone_set() from common.inc (in a previous version of this patch) into bootstrap.inc, you resolved the issue I was having with update.php. So nevermind the @.

c960657’s picture

Small nit:

+ * Sets default time zone for date/time functions to the configured time zone.

This should be “Set” instead of “Sets” (see http://drupal.org/node/1354#functions).

Apart from that this looks RTBC to me.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
4.48 KB

Ok, now "Set". Note, bootstrap.inc function documentation could use some clean up in this area.

c960657’s picture

Status: Needs review » Reviewed & tested by the community

I'd say this is ready to go in.

sun’s picture

Can someone explain to me (and in the code) why we need error-suppression here?

+    $timezone = variable_get('date_default_timezone', @date_default_timezone_get());
mfb’s picture

FileSize
4.52 KB

I added a short code comment.
Long answer is that PHP can fallback to getting the default time zone from several different sources, some of which ("Reading the TZ environment variable (if non empty)" and "Querying the host operating system (if supported and allowed by the OS)") trigger PHP strict notices. We want to ignore those notices because we really do want to get it from those sources if needed, before setting it properly.
We could add extra verbage to the code comment if it's useful...

sun’s picture

Status: Reviewed & tested by the community » Needs work

2 issues:

+    // Ignore PHP strict notice if time zone has not yet been set.
+    $timezone = variable_get('date_default_timezone', @date_default_timezone_get());
+  }
+  date_default_timezone_set($timezone);

What's the value of $timezone if no time zone has been set yet?

+    variable_set('date_default_timezone', date_default_timezone_get());

Why don't we apply the same error suppression here? (Not that I like error suppression [it should be avoided at all costs], but this is inconsistent.)

mfb’s picture

Status: Needs work » Needs review
  1. If not yet set it will be "Reading the TZ environment variable (if non empty), Reading the value of the date.timezone ini option (if set), or Querying the host operating system (if supported and allowed by the OS). If none of the above succeed, date_default_timezone_get will return a default timezone of UTC." I'm just copy/pasting the PHP function documentation so not sure a code comment is needed.
  2. Because drupal has already bootstrapped when this piece of code runs, meaning time zone was already set so it shouldn't be possible to trigger a strict notice.
NancyDru’s picture

Patch works for me, although the line numbers were way off.

mfb’s picture

FileSize
4.49 KB
NancyDru’s picture

Was there any difference besides the line numbers?

mfb’s picture

Oops, I swear I typed in a comment! too many tabs.. Yes that was just a re-roll to fix the line numbers.

NancyDru’s picture

Then I will not reapply it.

Damien Tournoud’s picture

Status: Needs review » Needs work

Oh, what an horrible function name: drupal_date_default_timezone_set(). I know that it is named after the corresponding PHP function (date_default_timezone_set()), and this is how we do that elsewhere. But in that case it doesn't seem wise: those two functions have different purpose and different signatures.

I suggest we implement drupal_get_user_timezone() as:

/**
 * Return the timezone of the current user.
 */
function drupal_get_user_timezone() {
  global $user;
  if (variable_get('configurable_timezones', 1) && $user->uid && $user->timezone) {
    $timezone = $user->timezone;
  }
  else {
    // Ignore PHP strict notice if time zone has not yet been set *in the php.ini configuration*.
    $timezone = variable_get('date_default_timezone', @date_default_timezone_get());
  }
  return $timezone;
}

(notice the clarification on the comment)

and that we do:

date_default_timezone_set(drupal_get_user_timezone());

in _drupal_bootstrap().

mfb’s picture

Status: Needs work » Needs review
FileSize
4.48 KB

OK done.

Status: Needs review » Needs work

The last submitted patch failed testing.

c960657’s picture

Status: Needs work » Needs review
FileSize
7.1 KB

Reroll.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
4.48 KB

reroll.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review

Cannot reproduce this failure.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
4.46 KB

Chasing HEAD.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
5.81 KB

Fixed a potential test failure.

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
5.78 KB

Chasing HEAD.

Status: Needs review » Needs work

The last submitted patch failed testing.

donquixote’s picture

subscribe.
I suddenly get these timezone warnings now that I have PHP 5.3

mfb’s picture

Status: Needs work » Needs review
FileSize
5.76 KB

Chasing HEAD

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
5.8 KB

Fixed install ($user does not exist during install)

Status: Needs review » Needs work

The last submitted patch failed testing.

mfb’s picture

Status: Needs work » Needs review
FileSize
7.06 KB

Argh, appears that bootstrap order changed.

mfb’s picture

FileSize
5.78 KB

Just noticed I included some debug code in #80

mfb’s picture

Status: Needs review » Closed (duplicate)

This needs more reviews but I merged it in to #348448: Always report E_STRICT errors so let's review it over there.

David_Rothstein’s picture

Priority: Minor » Normal
Status: Closed (duplicate) » Needs review

Seems like this issue should remain open - it's its own separate bug and there's plenty of discussion here about how to fix it.

Also, I'm tentatively upping this to "normal" because as far as I understand from #668496: Timezone error on D7 install (which I am marking duplicate of this), in the case of PHP 5.3 these warnings show up even when not in strict mode?

mfb’s picture

webchick suggested that this patch be merged into #348448: Always report E_STRICT errors, see http://drupal.org/node/348448#comment-2139926 so that is where it has been maintained. The last patch here no longer applies due to some bootstrap refactoring.

Sahin’s picture

I face the same issue at Drupal 7.0a1 installation, "Configure site" step (with IIS 5.1 and PHP 5.3.1)

This issue is discussed also at #615438: Date warnings, though the suggested temporary solution as

<?php
  $php_version = phpversion();
  if (!@date_default_timezone_get() and $php_version >= '5.3.0') {
    date_default_timezone_set('UTC');
  }
?>

is not limited to 5.3.0 (my case 5.3.1).

mfb’s picture

Status: Needs review » Closed (duplicate)

This patch was merged into #348448: Always report E_STRICT errors so setting to "duplicate" until someone convinces me to split it back out or does it themselves :)

drupalhung’s picture

Status: Closed (duplicate) » Needs review

#81: tz.patch queued for re-testing.

mfb’s picture

As I said in #84 this patch no longer applies, but fine, don't believe me :p

Status: Needs review » Needs work

The last submitted patch, tz.patch, failed testing.

Deslack’s picture

Status: Needs work » Patch (to be ported)
FileSize
726 bytes

Fixed the problem (in my case) in line 1814 that generated warnings.

mfb’s picture

Status: Patch (to be ported) » Closed (duplicate)

@Deslack this doesn't work, because PHP thinks that a "@" timestamp already has a time zone of UTC and ignores any time zone you pass in to date_create(). Example code:

 print date_format(date_create('@' . time(), timezone_open('Indian/Antananarivo')), 'r') . "\n";
print date_format(date_create('@' . time(), timezone_open('America/Los_Angeles')), 'r') . "\n"; 

The two formatted dates will be in the same (UTC) time zone.

See #84 for link to working version of this patch in #348448: Always report E_STRICT errors

wcndave’s picture

Hi, i am very new to drupal and have just installed 6.1.16, and notice that this issue is also occurring every time i edit a page.

it was first raised in 2008, and yet is still happening, and all the patches seem to be marked as failed.

do you know when this will be fixed? I seem to have seen someone showing me a drupal installation which got me interested in the first place that didn't have this issue.

Thanks

mfb’s picture

@wcndave: There should be some easy work-around in .htaccess or settings.php: setting a default time zone, changing the error reporting level, etc. Try adding this to your .htaccess (or Apache configuration) file: php_value date.timezone Europe/London

wcndave’s picture

adding to htaccess work perfectly, thank you!

mfb’s picture

FYI you can also set it to UTC (for GMT time) or any other valid time zone. Europe/London will use daylight saving/summer time.

b3liev3’s picture

I think that the best is just write in the php.ini the date.timezone. I wouldn't write anything in the bootstrap if it isn't strictly necessary.

Example:

date.timezone = Europe/Andorra

It usually is commented with a ';' so you should just remove the semicolon.

akalyptos’s picture

Status: Closed (duplicate) » Needs review

#80: tz.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, tz.patch, failed testing.

mfb’s picture

Status: Needs work » Closed (duplicate)
studiotwelve’s picture

Not sure if this is still relevant but there's a global fix for this here: http://groups.drupal.org/node/17970#comment-179313

From: uberhacker


Put the following in settings.php:
ini_set('date.timezone', date_default_timezone_get());

alanom’s picture

@studiotwelve: Thanks! That worked for me putting it into sites/default/settings.php, and in one line cleared not only several pages of these errors, but also a mysterious MySQL error while setting up Date and Calendar modules.

jjoseph’s picture

#102 Worked perfectly!! Thank you studiowelve and uberhacker!

Renee S’s picture

Ditto, @studiotwelve @uberhacker. Thanks =)

aamercado’s picture

#102 Worked !!. I'm using Drupal 6.22 and this solution worked for me. Thanks!!!

selfsimilar’s picture

#102 worked for me under PHP 5.3.8 and Drupal 6.22

manfer’s picture

Status: Closed (duplicate) » Active

This was marked as a duplicate of #348448: Always report E_STRICT errors and as that issue is for drupal 8 it was patched in drupal 8 and backported to drupal 7.

The error is still present in drupal 6 as no solution to this seems to have been backported to drupal 6 though there have been some new releases of drupal 6 since this issue started. Isn't there a way to solve this in core on drupal 6 or the best solution is to just use the ini_set config in settings.php (#102) for people that wants to run drupal 6 in PHP 5.2+?

The problem is there in drupal 6.22 node module. Unless solved in dev version the problem persists.

manfer’s picture

Version: 7.x-dev » 6.22
geerlingguy’s picture

Just wanted to report that, when the central timezone hit daylight savings time, the use of the tip in #102 started producing tons of errors in my logs (as the reported timezone was no longer 'America/Chicago', but 'CST/-6.0/no DST'. Changing the value to 'America/Chicago' explicitly fixed the errors for me. Annoying, but I'm happy to not have a huge amount of logs showing that particular error :)

More on this: http://www.midwesternmac.com/blogs/jeff-geerling/drupal-6x-and-php-53x-date

dmon000’s picture

#102 Worked perfectly!! Thank you studiowelve and uberhacker!

mrcniceguy’s picture

#102 Worked perfectly for me too))) Thank you studiowelve and uberhacker!

Sanjay Chauhan’s picture

warning: strtotime(): It is not safe to rely on the system's timezone settings. You are*required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We
selected 'America/New_York' for 'EST/-5.0/no DST'

Anyways, open up the file sites/all/modules/node/node.module and paste this bit of code right under the <?php at the top:
date_default_timezone_set("America/Chicago");
Obviously set the "America/Chicago" part to whatever timezone you are in currently.

More on this: http://drupalindia.net/forum-topic/drupal-theme-error/warning-strtotime-...

szabeh’s picture

Put the following in settings.php:
ini_set('date.timezone', date_default_timezone_get());
this is work

tnx

Robin Millette’s picture

ikiam’s picture

For me the solution of studiowelve and uberhacker! didn`t work... a error message. I just write:

date.timezone = "America/Guayaquil"

in the php.ini

I dont know if it will be a bad solution

altavis’s picture

@116
Thanks szabeh, works like a charm.

Stathes’s picture

@116 did not work for me

Stathes’s picture

118 did work for me however I used his exact syntax == date.timezone = "America/Guayaquil"

criscom’s picture

Version: 6.22 » 6.34
Issue summary: View changes

defining date.timezone = Europe/Vienna in php.ini worked for me

Status: Active » Closed (outdated)

Automatically closed because Drupal 6 is no longer supported. If the issue verifiably applies to later versions, please reopen with details and update the version.