2

I'm developing a radio site where show times are displayed. Since it's an Internet radio station, I need to be able to display times in the user's timezone.

I'm able to detect which timezone a user is using (eg. Europe/London), but I don't know how to make Drupal use that timezone.

Is there any way to programmatically override Drupal's default timezone to instead use the timezone I detected?

I've looked through the documentation, but I have not been able to find a way for achieving this.

2 Answers 2

2

drupal_get_user_timezone() is the main function that retrieves the user's zone (based on a configured user setting, site setting, or PHP's date_default_timezone_get() depending on site/user settings).

This function's implementation is based off of retrieving configuration settings and native PHP function. There's no way to override that short of trying to redefine to this function (if you don't mind a solution that is a bit of hack).

An alternative to that would provide some wrapper function in a custom module. For example:

function mymodule_get_timezone() {
  // @TODO: At timezone lookup retrieval based on IP/Whatever
}

function mymodule_get_user_timezone() {
  // Or \Drupal::currentUser()->isAnonymous() in D8
  return user_is_anonymous() ? mymodule_get_timezone() : drupal_get_user_timezone();
}

Then reference mymodule_get_user_timezone() wherever you need to insert your own discovered timezone.

2
  • Actually, for the anonymous users, drupal_get_user_timezone() just returns the default timezone set in PHP, which could not be the correct timezone.
    – apaderno
    Jun 12, 2016 at 5:22
  • @kiamlaluno For anon, it will check the system default first (whatever is set in config timezone.default, lines ~521--524 in 8.2.x/bootstrap.inc), then default back to the PHP setting. 7.x is essentially the same, but it checks the date_default_timezone variable first.
    – mpdonadio
    Jun 12, 2016 at 15:32
2

Drupal allows users to set their own timezone, but that is only for authenticated users; there isn't a setting for anonymous users. Even drupal_get_user_timezone() doesn't return anything useful for anonymous users, since (for anonymous users) it returns the default timezone set in PHP (i.e. on server side).

The only way to detect the user timezone is from JavaScript, which is exactly what Drupal does to auto detect the timezone used as default in the user profile edit form, when the user has not set their own timezone, yet. See misc/timezone.js.

  var dateString = Date();
  // In some client environments, date strings include a time zone
  // abbreviation, between 3 and 5 letters enclosed in parentheses,
  // which can be interpreted by PHP.
  var matches = dateString.match(/\(([A-Z]{3,5})\)/);
  var abbreviation = matches ? matches[1] : 0;

  // For all other client environments, the abbreviation is set to "0"
  // and the current offset from UTC and daylight saving time status are
  // used to guess the time zone.
  var dateNow = new Date();
  var offsetNow = dateNow.getTimezoneOffset() * -60;

  // Use January 1 and July 1 as test dates for determining daylight
  // saving time status by comparing their offsets.
  var dateJan = new Date(dateNow.getFullYear(), 0, 1, 12, 0, 0, 0);
  var dateJul = new Date(dateNow.getFullYear(), 6, 1, 12, 0, 0, 0);
  var offsetJan = dateJan.getTimezoneOffset() * -60;
  var offsetJul = dateJul.getTimezoneOffset() * -60;

  var isDaylightSavingTime;
  // If the offset from UTC is identical on January 1 and July 1,
  // assume daylight saving time is not used in this time zone.
  if (offsetJan == offsetJul) {
    isDaylightSavingTime = '';
  }
  // If the maximum annual offset is equivalent to the current offset,
  // assume daylight saving time is in effect.
  else if (Math.max(offsetJan, offsetJul) == offsetNow) {
    isDaylightSavingTime = 1;
  }
  // Otherwise, assume daylight saving time is not in effect.
  else {
    isDaylightSavingTime = 0;
  }

  // Submit request to the system/timezone callback and set the form field
  // to the response time zone. The client date is passed to the callback
  // for debugging purposes. Submit a synchronous request to avoid database
  // errors associated with concurrent requests during install.
  var path = 'system/timezone/' + abbreviation + '/' + offsetNow + '/' + isDaylightSavingTime;
  var element = this;
  $.ajax({
    async: false,
    url: settings.basePath,
    data: { q: path, date: dateString },
    dataType: 'json',
    success: function (data) {
      if (data) {
        $(element).val(data);
      }
    }
  });

You can use a similar approach.

  • Using JavaScript, you detect the timezone for the user
  • You make an AJAX call to make Drupal (or your module) know the timezone

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.