If you have had a Canadian user complain that Canada is missing from the Drupal 7 time zone list, here's how to make them happy again.
First, the cause of this is that for some reason (I don't actually know why, but I'm sure it's a good reason) Canada, and some other countries are not returned by the php function timezone_identifiers_list().
To get Canada into the list we need to add an argument to the function: timezone_identifiers_list(DateTimeZone::ALL_WITH_BC); Now the actual function that populates the User Time Zone List is in the core function system_time_zones() and since hacking core is a sin, here's how to add Canada to the list.
timezone_fix.module
function timezone_fix_form_user_profile_form_alter(&$form, &$form_state) {
$form['#after_build'][] = 'timezone_fix_timezone_modify';
}
function timezone_fix_timezone_modify($form, &$form_state) {
$blank = null;
$zonelist = timezone_identifiers_list(DateTimeZone::ALL_WITH_BC);
$zones = $blank ? array('' => t('- None selected -')) : array();
foreach ($zonelist as $zone) {
// Because many time zones exist in PHP only for backward compatibility
// reasons and should not be used, the list is filtered by a regular
// expression.
if (preg_match ('!^((Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Canada|Europe|Indian|Pacific)/|UTC$)!', $zone)) {
$zones[$zone] = t('@zone: @date', array('@zone' => t(str_replace ('_', ' ', $zone)), '@date' => format_date(REQUEST_TIME, 'custom', ' O', $zone)));
}
}
// Sort the translated time zones alphabetically.
asort ($zones);
$form['timezone']['timezone']['#options'] = $zones;
return $form;
}

