Needs work
Project:
Drupal core
Version:
main
Component:
base system
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
17 Feb 2011 at 17:15 UTC
Updated:
30 Jan 2023 at 21:31 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
catchIsolated the three functions in a one off PHP file. All three load the timezones database from system.
We can probably avoid calling them all during page cache, but may have to eat this for full bootstrap.
Comment #2
catchOK here's a patch.
Adds a new function drupal_set_configured_timezone(). This sets the user or site-wide timezone, but only if it's different from the timezone configured in php.ini (or if no timezone is configured). If neither the user, site-wide, or date.timezone is set, then we allow PHP to throw the E_STRICT (soon to be E_WARNING) - we can consider mitigating that but setting a timezone on install (and in an update for D7) if date.timezone isn't set, but that's not in the patch.
Confirmed that there's no meter long syscall in strace (unless the browser sends an if-modified-since header in which case you get one from strtotime() but we can't really help that).
Comment #4
berdir#2: timezone.patch queued for re-testing.
Comment #6
catch#2: timezone.patch queued for re-testing.
Comment #7
mattyoung commentedSubScribe
Comment #8
dries commented- What about calling this function
drupal_set_timezone()? I'm not sure that '_configured_' part adds value.- In the phpDoc I would explain why we want to set the timezone.
- With the patch,
drupal_get_user_timezone()is only called once. It took me a while to grok this patch. I think inliningdrupal_get_user_timezone()indrupal_set_(configured_)timezone()would improve readability -- might be a small clean-up. Only for D8.Comment #9
catchRenamed the function and added some phpdoc.
I'm not 100% we want to set the timezone for the request to the user's configured timezone indiscriminately to be honest, but haven't thought through the implications. However this issue doesn't change anything in terms of functionality apart from avoiding the @ nastiness and the syscall, but tried to leave that out of the comment.
I don't mind doing the in-lining in Drupal 8, although for that I'd also like to discuss the user vs. site priority across the request as well.
Comment #11
catchLooks like patch in #2 was committed by mistake in http://drupal.org/cvs?commit=502480
Comment #12
dries commentedI rolled back the accidental commit of #2.
Comment #13
bfroehle commented#9: timezone.patch queued for re-testing.
Comment #14
mfbThis patch causes notices during install: Notice: date_default_timezone_set(): Timezone ID '' is invalid in drupal_set_timezone() (line 1968 of includes/bootstrap.inc).
I'd say drupal_get_user_timezone() should return a valid time zone, which NULL is not. We could check for NULL and then fallback to @date_default_timezone_get():
or at least use UTC, which is the last resort of date_default_timezone_get():
return variable_get('date_default_timezone', 'UTC');By the way there's a typo in this comment,
// Note that is no site-wide timezone is setshould be if.Comment #15
catchAlright Damien suggested falling back to UTC in the other issue, I've done that although not as the default value of the variable, to account for the following situation:
date.timezone is set to EST in php.ini
No timezone is configured.
We don't want to set the timezone to UTC in this case - php.ini should take precedence if there's no other preference specified anywhere.
Also fixed the typo in the comment.
Comment #16
mfbThere's another problem with this approach. It doesn't account for the fact that the current value of the default time zone may be different from the date.timezone ini setting. See for example the FormatDateUnitTest, where we simulate a logged in user by setting the time zone.
The test fails if the date.timezone ini setting is America/Los_Angeles (the test user's time zone), but the logged in user running the test has some other time zone configured. The time zone needs to be changed by drupal_set_timezone(), but won't be because the test user's time zone is the same as date.timezone.
Comment #17
catchWhat about just removing that hunk from the patch then? Since in this case we do want to explicitly set it to something other than the default.
We might want to change drupal_set_timezone() to drupal_ensure_timezone(), but I'm not sure about that.
Comment #18
mfbOK the tests pass now in my environment. One minor thing, I believe elseif is preferred vs. else if.
Comment #19
catchYes you're right, changed just the else if -> elseif in this patch.
Comment #21
andypostIt looks strange a fallback to ini settings - shared hostings could have this setting unconfigured or wrong for sites they hosts.
I see no reason to use php defaults for site - maybe better use UTC.
#19 introduces a big api change drupal_get_user_timezone() now could return NULL (previously it was php defaults)
I think _drupal_init_timezone() is a better name because it actually initialize a timezone by setting it to user or system timezone...
Comment #22
pillarsdotnet commentedModified so that drupal_get_user_timezone() never returns NULL.
Comment #23
andypostdrupal_init_timezone() is a better name because it means just called once and drupal_set_timezone() supposes a mirror function drupal_get_timezone()
Powered by Dreditor.
Comment #24
mfbI'd agree re: init, since this function isn't guaranteed to actually set the time zone (as seen in the tests).
Comment #25
pillarsdotnet commentedbikeshedding.
Whatever...
Comment #26
andypostTo continue bikeshedding in terms of performance.
ini_get() is called twice probably
should be faster
EDIT: but this depends on PHP - memory allocation for variable could take more time then array key manipulation
Powered by Dreditor.
Comment #27
pillarsdotnet commentedBenchmarks?
Comment #28
catchI did some more testing of this using the patch from #25 on my localhost.
There is some caching of the timezone database in PHP 5.3. The first request it loads up about 50 different files, subsequent requests it looks more like this:
However with the patch we're skipping the syscall entirely, so this is definitely worth doing, but not 'major'.
I used this file to test with (rename timezone.txt to timezone.php). Attaching strace output with and without the patch.
It's not worth doing benchmarks, but this couldn't be any more in the critical path.
Comment #29
catchCan still be backported too.
Comment #30
droplet commentedPHP 5.3, 10 nodes with 10 images, load 5 times for each.
Comment #31
catch@droplet it looks like you have xdebug enabled as an extension - this causes a lot of calls to gettimeofday, any chance you could try again without it?
Comment #32
droplet commentedYes, disable Xdebug reduce a bit of calls. But i think the big different it you are tested on anonymous users and Im logged.
here is the result of dsiable xdebug and anony user (load homepage with 1 node 5 times)
Comment #33
pounardJust in case, I ended up on these calls by having a breakpoint in the error handler, in D7 we can do this straight forward patch (that will avoid most calls):
Replace this code (bootstrap.inc line 2212):
By this code:
I will post a patch in D7 only bug since D8 seems to diverge too deeply with D7 at this stade.
Comment #36
andypostas PHP 5.4 requirement it makes more sense to clean-up.
Also most of core use UTC:
Comment #37
andypostalso
drupal_get_user_timezone()is the only pita finally clean-up global userComment #45
andypostFaced with that again
Comment #47
andypostComment #48
ilya.no commentedRerolled patch from #25.
Comment #49
andypostComment #51
andypostComment #62
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #63
catch#3009377: Replace drupal_get_user_timezone with a date_default_timezone_get() and an event listener refactored this a lot, but not sure if it made things better or worse.
The issue is that date_default_timezone_set() validates the timezone it is passed, and to validate it, it has to load the list of all timezones from the operating system to check against that.
I think we can still check in TimezoneResolver::setDefaultTimeZone() whether the timezone that we would set is identical to what's already set in php.ini, and avoid setting it if so. Will need a before and after strace to confirm it actually makes a difference.