? drupal_71.patch
? format_date_3.patch
? sites/default/settings.php
Index: install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.62
diff -u -p -r1.62 install.php
--- install.php	25 Jun 2007 12:44:11 -0000	1.62
+++ install.php	29 Jun 2007 03:14:36 -0000
@@ -888,22 +888,39 @@ function install_configure_form() {
     '#weight' => 0,
   );
 
-  $zones = _system_zonelist();
-
   $form['server_settings'] = array(
     '#type' => 'fieldset',
     '#title' => st('Server settings'),
     '#collapsible' => FALSE,
   );
-  $form['server_settings']['date_default_timezone'] = array(
-    '#type' => 'select',
-    '#title' => st('Default time zone'),
-    '#default_value' => variable_get('date_default_timezone', 0),
-    '#options' => $zones,
-    '#description' => st('By default, dates in this site will be displayed in the chosen time zone.'),
-    '#weight' => 5,
-  );
-
+  if (date_handle_timezones()) {
+    $form['server_settings']['date_default_offset'] = array(
+      '#type' => 'hidden',
+      '#value' => variable_get('date_default_offset', NULL),
+    );
+    $form['server_settings']['date_default_timezone'] = array(
+      '#type' => 'select',
+      '#title' => t('Default time zone'),
+      '#default_value' => variable_get('date_default_timezone', NULL),
+      '#options' => date_zone_names(),
+      '#description' => st('By default, dates in this site will be displayed in the chosen time zone.'),
+      '#weight' => 5,
+      '#submit' => array('system_timezone_update_site' => array('date_default_timezone')),
+    );
+  }
+  else {
+    $form['server_settings']['date_default_timezone'] = array(
+      '#type' => 'hidden',
+      '#value' => variable_get('date_default_timezone', NULL),
+    );
+    $form['server_settings']['date_default_offset'] = array(
+      '#type' => 'select',
+      '#title' => t('Default time zone'),
+      '#default_value' => variable_get('date_default_offset', NULL),
+      '#options' => date_zone_offsets(),
+      '#description' => st('By default, dates in this site will be displayed in the chosen time zone.'),
+    );
+  }
   drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
   // We add these strings as settings because JavaScript translation does not
   // work on install time.
@@ -958,7 +975,9 @@ function install_configure_form_submit($
 
   variable_set('site_name', $form_state['values']['site_name']);
   variable_set('site_mail', $form_state['values']['site_mail']);
+  variable_set('date_default_offset', $form_state['values']['date_default_offset']);
   variable_set('date_default_timezone', $form_state['values']['date_default_timezone']);
+  date_update_sitezone($form, $form_state);
 
   // Turn this off temporarily so that we can pass a password through.
   variable_set('user_email_verification', FALSE);
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.666
diff -u -p -r1.666 common.inc
--- includes/common.inc	28 Jun 2007 07:48:40 -0000	1.666
+++ includes/common.inc	29 Jun 2007 03:14:38 -0000
@@ -1071,31 +1071,27 @@ function format_interval($timestamp, $gr
  * @param $type
  *   The format to use. Can be "small", "medium" or "large" for the preconfigured
  *   date formats. If "custom" is specified, then $format is required as well.
- * @param $format
- *   A PHP date format string as required by date(). A backslash should be used
- *   before a character to avoid interpreting the character as part of a date
- *   format.
- * @param $timezone
- *   Time zone offset in seconds; if omitted, the user's time zone is used.
- * @param $langcode
- *   Optional language code to translate to a language other than
- *   what is used to display the page.
+ * @param $params
+ *   An optional array of extra parameters:
+ *     'langcode'
+ *       Optional language code to translate to a language other than
+ *       what is used to display the page.
+ *     'format'
+ *       A PHP date format string as required by date(). A backslash 
+ *       should be used before a character to avoid interpreting the 
+ *       character as part of a date format.
+ *     'timezone'
+ *       A timezone name as returned by date_zone_names(); if omitted,
+ *       the user's timezone is used.  Used only in native timezone 
+ *       handling mode.
+ *     'offset'
+ *       Time zone offset in seconds; if omitted, the user's offset is 
+ *       used.  Used only in legacy timezone handling mode.
  * @return
  *   A translated date string in the requested format.
  */
-function format_date($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) {
-  if (!isset($timezone)) {
-    global $user;
-    if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
-      $timezone = $user->timezone;
-    }
-    else {
-      $timezone = variable_get('date_default_timezone', 0);
-    }
-  }
-
-  $timestamp += $timezone;
-
+function format_date($timestamp, $type = 'medium', $params = array()) {
+  $langcode = isset($params['langcode']) ? $params['langcode'] : NULL;
   switch ($type) {
     case 'small':
       $format = variable_get('date_format_short', 'm/d/Y - H:i');
@@ -1104,40 +1100,91 @@ function format_date($timestamp, $type =
       $format = variable_get('date_format_long', 'l, F j, Y - H:i');
       break;
     case 'custom':
-      // No change to format
+      $format = $params['format'];
       break;
     case 'medium':
     default:
       $format = variable_get('date_format_medium', 'D, m/d/Y - H:i');
   }
-
   $max = strlen($format);
   $date = '';
-  for ($i = 0; $i < $max; $i++) {
-    $c = $format[$i];
-    if (strpos('AaDFlM', $c) !== FALSE) {
-      $date .= t(gmdate($c, $timestamp), array(), $langcode);
-    }
-    else if (strpos('BdgGhHiIjLmnsStTUwWYyz', $c) !== FALSE) {
-      $date .= gmdate($c, $timestamp);
-    }
-    else if ($c == 'r') {
-      $date .= format_date($timestamp - $timezone, 'custom', 'D, d M Y H:i:s O', $timezone, $langcode);
+  if (date_handle_timezones()) {
+    // Using native timezone handling mode.
+    if (isset($params['timezone'])) {
+      $timezone = $params['timezone'];
     }
-    else if ($c == 'O') {
-      $date .= sprintf('%s%02d%02d', ($timezone < 0 ? '-' : '+'), abs($timezone / 3600), abs($timezone % 3600) / 60);
+    else {
+      global $user;
+      if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
+        $timezone = $user->timezone;
+      }
+      else {
+        $timezone = variable_get('date_default_timezone', 'UTC');
+      }
     }
-    else if ($c == 'Z') {
-      $date .= $timezone;
+    $date_time = date_create(gmdate('c', $timestamp));
+    date_timezone_set($date_time, timezone_open($timezone));
+    for ($i = 0; $i < $max; $i++) {
+      $c = $format[$i];
+      // AM/pm, days of the week, months, timezone names, and 
+      // timezone abbreviations can be localized.
+      if (strpos('AaeDFlMT', $c) !== FALSE) {
+        $date .= t(date_format($date_time, $c), array(), $langcode);
+      }
+      else if (strpos('BcdGgHhIijLmNnOoPrSstUuWwYyZz', $c) !== FALSE) {
+        $date .= date_format($date_time, $c);
+      }
+      else if ($c == 'r') {
+        $date .= format_date($timestamp, 'custom', array('format' => 'D, d M Y H:i:s O', 'timezone' => $timezone, 'langcode' => $langcode));
+      }
+      else if ($c == '\\') {
+        $date .= $format[++$i];
+      }
+      else {
+        $date .= $c;
+      }
     }
-    else if ($c == '\\') {
-      $date .= $format[++$i];
+  }
+  else {
+    // Using legacy timezone handling mode (offsets).
+    if (isset($params['offset'])) {
+      $offset = $params['offset'];
     }
     else {
-      $date .= $c;
+      global $user;
+      if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->offset)) {
+        $offset = $user->offset;
+      }
+      else {
+        $offset = variable_get('date_default_offset', 0);
+      }
+    }
+    $timestamp += $offset;
+    for ($i = 0; $i < $max; $i++) {
+      $c = $format[$i];
+      if (strpos('AaDFlM', $c) !== FALSE) {
+        $date .= t(gmdate($c, $offset), array(), $langcode);
+      }
+      else if (strpos('BdgGhHiIjLmnsStTUwWYyz', $c) !== FALSE) {
+        $date .= gmdate($c, $offset);
+      }
+      else if ($c == 'r') {
+        $date .= format_date($timestamp - $offset, 'custom', array('format' => 'D, d M Y H:i:s O', 'offset' => $offset, 'langcode' => $langcode));
+      }
+      else if ($c == 'O') {
+        $date .= sprintf('%s%02d%02d', ($offset < 0 ? '-' : '+'), abs($offset / 3600), abs($offset % 3600) / 60);
+      }
+      else if ($c == 'Z') {
+        $date .= $offset;
+      }
+      else if ($c == '\\') {
+        $date .= $format[++$i];
+      }
+      else {
+        $date .= $c;
+      }
     }
   }
-
   return $date;
 }
 
Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.208
diff -u -p -r1.208 form.inc
--- includes/form.inc	28 Jun 2007 07:48:40 -0000	1.208
+++ includes/form.inc	29 Jun 2007 03:14:41 -0000
@@ -1261,9 +1261,9 @@ function theme_date($element) {
 function expand_date($element) {
   // Default to current date
   if (empty($element['#value'])) {
-    $element['#value'] = array('day' => format_date(time(), 'custom', 'j'),
-                            'month' => format_date(time(), 'custom', 'n'),
-                            'year' => format_date(time(), 'custom', 'Y'));
+    $element['#value'] = array('day' => format_date(time(), 'custom', array('format' => 'j')),
+                            'month' => format_date(time(), 'custom', array('format' => 'n')),
+                            'year' => format_date(time(), 'custom', array('format' => 'Y')));
   }
 
   $element['#tree'] = TRUE;
@@ -1316,7 +1316,7 @@ function date_validate($form) {
  * Helper function for usage with drupal_map_assoc to display month names.
  */
 function map_month($month) {
-  return format_date(gmmktime(0, 0, 0, $month, 2, 1970), 'custom', 'M', 0);
+  return format_date(gmmktime(0, 0, 0, $month, 2, 1970), 'custom', array('format' => 'M', 'offset' => 0, 'timezone' => 'UTC'));
 }
 
 /**
Index: modules/aggregator/aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.345
diff -u -p -r1.345 aggregator.module
--- modules/aggregator/aggregator.module	5 Jun 2007 12:13:21 -0000	1.345
+++ modules/aggregator/aggregator.module	29 Jun 2007 03:14:41 -0000
@@ -1399,7 +1399,7 @@ function theme_aggregator_page_item($ite
     $source_date = t('%ago ago', array('%ago' => format_interval(time() - $item->timestamp)));
   }
   else {
-    $source_date = format_date($item->timestamp, 'custom', variable_get('date_format_medium', 'D, m/d/Y - H:i'));
+    $source_date = format_date($item->timestamp);
   }
 
   $output .= "<div class=\"feed-item\">\n";
Index: modules/blogapi/blogapi.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.module,v
retrieving revision 1.106
diff -u -p -r1.106 blogapi.module
--- modules/blogapi/blogapi.module	30 Apr 2007 17:03:23 -0000	1.106
+++ modules/blogapi/blogapi.module	29 Jun 2007 03:14:42 -0000
@@ -205,7 +205,7 @@ function blogapi_blogger_new_post($appke
   }
 
   if (user_access('administer nodes') && !isset($edit['date'])) {
-    $edit['date'] = format_date(time(), 'custom', 'Y-m-d H:i:s O');
+    $edit['date'] = format_date(time(), 'custom', array('format' => 'Y-m-d H:i:s O'));
   }
 
   node_invoke_nodeapi($edit, 'blogapi new');
@@ -269,7 +269,7 @@ function blogapi_blogger_edit_post($appk
   }
 
   if (user_access('administer nodes') && !isset($edit['date'])) {
-    $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+    $node->date = format_date($node->created, 'custom', array('format' => 'Y-m-d H:i:s O'));
   }
   $node = node_submit($node);
   node_save($node);
@@ -644,7 +644,7 @@ function _blogapi_mt_extra(&$node, $stru
 
   // dateCreated
   if ($struct['dateCreated']) {
-    $node->date = format_date(mktime($struct['dateCreated']->hour, $struct['dateCreated']->minute, $struct['dateCreated']->second, $struct['dateCreated']->month, $struct['dateCreated']->day, $struct['dateCreated']->year), 'custom', 'Y-m-d H:i:s O');
+    $node->date = format_date(mktime($struct['dateCreated']->hour, $struct['dateCreated']->minute, $struct['dateCreated']->second, $struct['dateCreated']->month, $struct['dateCreated']->day, $struct['dateCreated']->year), 'custom', array('format' => 'Y-m-d H:i:s O'));
   }
 
   if ($was_array) {
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.556
diff -u -p -r1.556 comment.module
--- modules/comment/comment.module	24 Jun 2007 10:09:52 -0000	1.556
+++ modules/comment/comment.module	29 Jun 2007 03:14:43 -0000
@@ -1504,7 +1504,7 @@ function comment_form(&$form_state, $edi
         $date = $edit['date'];
       }
       else {
-        $date = format_date($edit['timestamp'], 'custom', 'Y-m-d H:i O');
+        $date = format_date($edit['timestamp'], 'custom', array('format' => 'Y-m-d H:i O'));
       }
 
       $form['admin'] = array(
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.842
diff -u -p -r1.842 node.module
--- modules/node/node.module	28 Jun 2007 07:48:40 -0000	1.842
+++ modules/node/node.module	29 Jun 2007 03:14:47 -0000
@@ -2087,7 +2087,7 @@ function node_object_prepare(&$node) {
     }
 
     if (!isset($node->date)) {
-      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+      $node->date = format_date($node->created, 'custom', array('format' => 'Y-m-d H:i:s O'));
     }
   }
 
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.124
diff -u -p -r1.124 system.install
--- modules/system/system.install	26 Jun 2007 20:24:19 -0000	1.124
+++ modules/system/system.install	29 Jun 2007 03:14:49 -0000
@@ -3421,6 +3421,19 @@ function system_update_6024() {
 }
 
 /**
+ * Rename user->timezone to user->offset and add new user->timezone to hold timezone names.
+ * Alter variables to match new schema.
+ */
+function system_update_6025() {
+  $ret = array();
+  db_change_field($ret, 'users', 'timezone', 'offset', array('type' => 'varchar', 'length' => 8, 'not null' => FALSE, 'default' => NULL));
+  db_add_field($ret, 'users', 'timezone', array('type' => 'varchar', 'length' => 50, 'not null' => FALSE, 'default' => NULL));
+  variable_set('date_default_offset', variable_get('date_default_timezone', NULL));
+  variable_set('date_default_timezone', NULL);
+  return $ret;
+}
+
+/**
  * @} End of "defgroup updates-5.x-to-6.x"
  * The next series of updates should start at 7000.
  */
Index: modules/system/system.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.js,v
retrieving revision 1.8
diff -u -p -r1.8 system.js
--- modules/system/system.js	8 Jun 2007 12:51:59 -0000	1.8
+++ modules/system/system.js	29 Jun 2007 03:14:49 -0000
@@ -54,7 +54,7 @@ Drupal.cleanURLsInstallCheck = function(
 
 Drupal.installDefaultTimezone = function() {
   var offset = new Date().getTimezoneOffset() * -60;
-  $("#edit-date-default-timezone").val(offset);
+  $("#edit-date-default-offset").val(offset);
 };
 
 /**
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.499
diff -u -p -r1.499 system.module
--- modules/system/system.module	28 Jun 2007 00:48:26 -0000	1.499
+++ modules/system/system.module	29 Jun 2007 03:14:52 -0000
@@ -373,24 +373,45 @@ function system_user($type, $edit, &$use
     $form['theme_select'] = system_theme_select_form(t('Selecting a different theme will change the look and feel of the site.'), isset($edit['theme']) ? $edit['theme'] : NULL, 2);
 
     if (variable_get('configurable_timezones', 1)) {
-      $zones = _system_zonelist();
+      $zones = date_zone_offsets();
       $form['timezone'] = array(
         '#type' => 'fieldset',
         '#title' => t('Locale settings'),
         '#weight' => 6,
         '#collapsible' => TRUE,
       );
-      $form['timezone']['timezone'] = array(
-        '#type' => 'select',
-        '#title' => t('Time zone'),
-        '#default_value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', 0),
-        '#options' => $zones,
-        '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'),
-      );
+      if (date_handle_timezones()) {
+        $form['timezone']['offset'] = array(
+          '#type' => 'hidden',
+          '#value' => strlen($edit['offset']) ? $edit['offset'] : variable_get('date_default_offset', NULL),
+        );
+        $form['timezone']['timezone'] = array(
+          '#type' => 'select',
+          '#title' => t('Default time zone'),
+          '#default_value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', NULL),
+          '#options' => date_zone_names(),
+          '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'),
+        );
+      }
+      else {
+        $form['timezone']['timezone'] = array(
+          '#type' => 'hidden',
+          '#value' => strlen($edit['timezone']) ? $edit['timezone'] : variable_get('date_default_timezone', NULL),
+        );
+        $form['timezone']['offset'] = array(
+          '#type' => 'select',
+          '#title' => t('Default time zone'),
+          '#default_value' =>strlen($edit['offset']) ? $edit['offset'] : variable_get('date_default_offset', NULL),
+          '#options' => date_zone_offsets(),
+          '#description' => t('Select your current local time. Dates and times throughout this site will be displayed using this time zone.'),
+        );
+      }
     }
-
     return $form;
   }
+  elseif ($type == 'submit') {
+    date_update_userzone($edit, $user);
+  }
 }
 
 /**
@@ -542,17 +563,6 @@ function theme_system_theme_select_form(
   return $output;
 }
 
-function _system_zonelist() {
-  $timestamp = time();
-  $zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4, 5, 5.5, 5.75, 6, 6.5, 7, 8, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 14);
-  $zones = array();
-  foreach ($zonelist as $offset) {
-    $zone = $offset * 3600;
-    $zones[$zone] = format_date($timestamp, 'custom', variable_get('date_format_long', 'l, F j, Y - H:i') .' O', $zone);
-  }
-  return $zones;
-}
-
 function system_site_information_settings() {
   $form['site_name'] = array(
     '#type' => 'textfield',
@@ -818,6 +828,102 @@ function system_rss_feeds_settings() {
   return system_settings_form($form);
 }
 
+/**
+ * Test whether the system can use native php timezone handling.
+ * @todo This may need more than just a version comparison.
+ */
+function date_handle_timezones() {
+  return version_compare(PHP_VERSION, '5.1', '>');
+}
+
+function date_zone_names() {
+  $zone_names = array();
+  if (date_handle_timezones()) {
+    $zone_names = drupal_map_assoc(DateTimeZone::listIdentifiers());
+    // Make sure it is possible to leave timezone unset.
+    $zone_names = array('' => '') + $zone_names;
+  }
+    // Create a method for other modules to intervene in timezone listing.
+  foreach (module_implements('timezone_alter') as $name) {
+    $function = $name .'_timezone_alter';
+    $zone_names = $function('zone names', array('zone_names' => $zone_names));
+  }
+  return $zone_names;
+}
+
+function date_zone_offsets() {
+  $timestamp = time();
+  $zonelist = array(-11, -10, -9.5, -9, -8, -7, -6, -5, -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4, 5, 5.5, 5.75, 6, 6.5, 7, 8, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 14);
+  $zones = array();
+  foreach ($zonelist as $offset) {
+    $zone = $offset * 3600;
+    $zones[$zone] = format_date($timestamp, 'custom', array('format' => variable_get('date_format_long', 'l, F j, Y - H:i') .' O', 'offset' => $zone));
+  }
+  return $zones;
+}
+
+function date_update_sitezone(&$form, &$form_state) {
+  if (!isset($form_state['values']['date_default_timezone'])) return;
+  $timezone = $form_state['values']['date_default_timezone'];
+  if (date_handle_timezones()) {
+    if (!empty($timezone)) {
+      variable_set('date_default_timezone', $timezone);
+    }
+    else {
+      $timezone = variable_get('date_default_timezone', NULL);
+    }
+    $dateTimeZone = new DateTimeZone($timezone);
+    $dateTime = new DateTime("now", $dateTimeZone);
+    variable_set('date_default_offset', $dateTimeZone->getOffset($dateTime));
+    $form['date_default_offset'] = $dateTimeZone->getOffset($dateTime);
+    $form_state['values']['date_default_offset'] = $dateTimeZone->getOffset($dateTime);
+  }
+  // Create a method for other modules to intervene when the site timezone changes.
+  foreach (module_implements('timezone_alter') as $name) {
+    $function = $name .'_timezone_alter';
+    $result = $function('site update', array(
+      'form' => $form,
+      'form_state' => $form_state,
+      'timezone' => $timezone,
+      'dateTimeZone' => $dateTimeZone,
+      'dateTime' => $dateTime));
+  }
+}
+
+function date_update_userzone(&$edit, &$user) {
+  if (!isset($edit['timezone'])) return;
+  $timezone = $edit['timezone'];
+  $uid = $user->uid;
+  if (date_handle_timezones()) {
+    if (!empty($uid) && !empty($timezone)) {
+      // Calling this with a uid will update that user's offset.
+      $dateTimeZone = new DateTimeZone($timezone);
+      $dateTime = new DateTime("now", $dateTimeZone);
+      db_query("UPDATE {users} SET timezone = '%s', offset = '%s' WHERE uid = %d", $timezone, $dateTimeZone->getOffset($dateTime), $uid);
+      $edit['offset'] = $dateTimeZone->getOffset($dateTime);
+    }
+    else {
+      // Calling this with an empty uid will update the offsets for all users.
+      $result = db_query("SELECT DISTINCT timezone FROM {users}");
+      while ($row = db_fetch_array($result)) {
+        $dateTimeZone = new DateTimeZone($row['timezone']);
+        $dateTime = new DateTime("now", $dateTimeZone);
+        db_query("UPDATE {users} SET offset = '%s' WHERE timezone = '%s'", $dateTimeZone->getOffset($dateTime), $row['timezone']);
+      }
+    }
+  }
+  // Create a method for other modules to intervene when the user timezone changes.
+  foreach (module_implements('timezone_alter') as $name) {
+    $function = $name .'_timezone_alter';
+    $result = $function('user update', array(
+      'edit' => $edit,
+      'user' => $user,
+      'timezone' => $timezone,
+      'dateTimeZone' => $dateTimeZone,
+      'dateTime' => $dateTime));
+  }
+}
+
 function system_date_time_settings() {
   drupal_add_js(drupal_get_path('module', 'system') .'/system.js', 'module');
   drupal_add_js(array('dateTime' => array('lookup' => url('admin/settings/date-time/lookup'))), 'setting');
@@ -827,7 +933,7 @@ if (Drupal.jsEnabled) {
   $(document).ready(Drupal.dateTimeAutoAttach);
 }', 'inline');
   // Date settings:
-  $zones = _system_zonelist();
+  $zones = date_zone_offsets();
 
   // Date settings: possible date formats
   $date_short = array('Y-m-d H:i', 'm/d/Y - H:i', 'd/m/Y - H:i', 'Y/m/d - H:i',
@@ -843,13 +949,13 @@ if (Drupal.jsEnabled) {
 
   // Date settings: construct choices for user
   foreach ($date_short as $f) {
-    $date_short_choices[$f] = format_date(time(), 'custom', $f);
+    $date_short_choices[$f] = format_date(time(), 'custom', array('format' => $f));
   }
   foreach ($date_medium as $f) {
-    $date_medium_choices[$f] = format_date(time(), 'custom', $f);
+    $date_medium_choices[$f] = format_date(time(), 'custom', array('format' => $f));
   }
   foreach ($date_long as $f) {
-    $date_long_choices[$f] = format_date(time(), 'custom', $f);
+    $date_long_choices[$f] = format_date(time(), 'custom', array('format' => $f));
   }
 
   $date_long_choices['custom'] = $date_medium_choices['custom'] = $date_short_choices['custom'] = t('Custom format');
@@ -859,13 +965,32 @@ if (Drupal.jsEnabled) {
     '#title' => t('Locale settings'),
   );
 
-  $form['locale']['date_default_timezone'] = array(
-    '#type' => 'select',
-    '#title' => t('Default time zone'),
-    '#default_value' => variable_get('date_default_timezone', 0),
-    '#options' => $zones,
-    '#description' => t('Select the default site time zone.')
-  );
+  if (date_handle_timezones()) {
+    $form['locale']['date_default_offset'] = array(
+      '#type' => 'hidden',
+      '#value' => variable_get('date_default_offset', NULL),
+    );
+    $form['locale']['date_default_timezone'] = array(
+      '#type' => 'select',
+      '#title' => t('Default time zone'),
+      '#default_value' => variable_get('date_default_timezone', NULL),
+      '#options' => date_zone_names(),
+      '#description' => t('Select the default site time zone.'),
+    );
+  }
+  else {
+    $form['locale']['date_default_timezone'] = array(
+      '#type' => 'hidden',
+      '#value' => variable_get('date_default_timezone', NULL),
+    );
+    $form['locale']['date_default_offset'] = array(
+      '#type' => 'select',
+      '#title' => t('Default time zone'),
+      '#default_value' => variable_get('date_default_offset', NULL),
+      '#options' => date_zone_offsets(),
+      '#description' => t('Select the default site time zone.'),
+    );
+  }
 
   $form['locale']['configurable_timezones'] = array(
     '#type' => 'radios',
@@ -908,7 +1033,7 @@ if (Drupal.jsEnabled) {
     '#title' => t('Custom short date format'),
     '#attributes' => array('class' => 'custom-format'),
     '#default_value' => $default_short_custom,
-    '#description' => t('A user-defined short date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', $default_short_custom))),
+    '#description' => t('A user-defined short date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', array('format' => $default_short_custom)))),
   );
 
   $date_format_medium = variable_get('date_format_medium', $date_medium[1]);
@@ -931,7 +1056,7 @@ if (Drupal.jsEnabled) {
     '#title' => t('Custom medium date format'),
     '#attributes' => array('class' => 'custom-format'),
     '#default_value' => $default_medium_custom,
-    '#description' => t('A user-defined medium date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', $default_medium_custom))),
+    '#description' => t('A user-defined medium date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', array('format' => $default_medium_custom)))),
   );
 
   $date_format_long = variable_get('date_format_long', $date_long[0]);
@@ -954,7 +1079,7 @@ if (Drupal.jsEnabled) {
     '#title' => t('Custom long date format'),
     '#attributes' => array('class' => 'custom-format'),
     '#default_value' => $default_long_custom,
-    '#description' => t('A user-defined long date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', $default_long_custom))),
+    '#description' => t('A user-defined long date format. See the <a href="@url">PHP manual</a> for available options. This format is currently set to display as <span>%date</span>.', array('@url' => 'http://php.net/manual/function.date.php', '%date' => format_date(time(), 'custom', array('format' => $default_long_custom)))),
   );
 
   $form = system_settings_form($form);
@@ -973,6 +1098,7 @@ function system_date_time_settings_submi
   if ($form_state['values']['date_format_long'] == 'custom') {
     $form_state['values']['date_format_long'] = $form_state['values']['date_format_long_custom'];
   }
+  date_update_sitezone($form, $form_state);
   return system_settings_form_submit($form, $form_state);
 }
 
@@ -980,7 +1106,7 @@ function system_date_time_settings_submi
  * Return the date for a given format string via Ajax.
  */
 function system_date_time_lookup() {
-  $result = format_date(time(), 'custom', $_GET['format']);
+  $result = format_date(time(), 'custom', array('format' => $_GET['format']));
   echo drupal_to_js($result);
   exit;
 }
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.809
diff -u -p -r1.809 user.module
--- modules/user/user.module	28 Jun 2007 07:48:41 -0000	1.809
+++ modules/user/user.module	29 Jun 2007 03:14:54 -0000
@@ -478,7 +478,7 @@ function user_fields() {
     }
     else {
       // Make sure we return the default fields at least
-      $fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'access', 'login', 'status', 'timezone', 'language', 'init', 'data');
+      $fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'access', 'login', 'status', 'timezone', 'offset', 'language', 'init', 'data');
     }
   }
 
@@ -2809,7 +2809,6 @@ function _user_categories($account) {
   }
 
   usort($categories, '_user_sort');
-
   return $categories;
 }
 
Index: modules/user/user.schema
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.schema,v
retrieving revision 1.2
diff -u -p -r1.2 user.schema
--- modules/user/user.schema	15 Jun 2007 07:15:25 -0000	1.2
+++ modules/user/user.schema	29 Jun 2007 03:14:54 -0000
@@ -58,7 +58,8 @@ function user_schema() {
       'access'    => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
       'login'     => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
       'status'    => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'),
-      'timezone'  => array('type' => 'varchar', 'length' => 8, 'not null' => FALSE),
+      'timezone'  => array('type' => 'varchar', 'length' => 50, 'not null' => FALSE),
+      'offset'    => array('type' => 'varchar', 'length' => 8, 'not null' => FALSE),
       'language'  => array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''),
       'picture'   => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
       'init'      => array('type' => 'varchar', 'length' => 64, 'not null' => FALSE, 'default' => ''),
@@ -66,7 +67,7 @@ function user_schema() {
     ),
     'indexes' => array(
       'access'  => array('access'),
-      'created' => array('created')
+      'created' => array('created'),
     ),
     'unique keys' => array('name' => array('name')),
     'primary key' => array('uid'),
