Index: date_api_ical.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/date/date_api_ical.inc,v
retrieving revision 1.19
diff -u -r1.19 date_api_ical.inc
--- date_api_ical.inc	9 Jan 2008 19:43:03 -0000	1.19
+++ date_api_ical.inc	16 Jan 2008 19:26:51 -0000
@@ -277,27 +277,68 @@
  *   date_ical_parse_duration(). This is not commonly used, so ignored for now.
  *   It will take more work to figure how to support that.
  */
+define('DATE_REGEX_ICAL_DATE', '/(\d{4})(\d{2})(\d{2})/');
+define('DATE_REGEX_ICAL_DATETIME', '/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(Z)?/');
 function date_ical_parse_date($field, $data) {
-  $tz = '';
+  // Turn the properties into a nice indexed array of
+  // array(PROPERTYNAME => PROPERTYVALUE); 
+  $field_parts = preg_split('/[;:]/', $field);
+  $properties = array();
+  foreach ($field_parts as $part) {
+    if (strpos($part, '=') !== false) {
+      $tmp = explode('=', $part);
+      $properties[$tmp[0]] = $tmp[1];
+    }
+  }
+  
+  // Make this a little more whitespace independent
   $data = trim($data);
-  $items = array('DATA' => $data);
-  if (substr($data, -1) == 'Z') {
+  
+  // Record if a time has been found
+  $has_time = false;
+  
+  // If a format is specified, parse it according to that format
+  if (isset($properties['VALUE'])) {
+    switch ($properties['VALUE']) {
+      case 'DATE':
+        preg_match (DATE_REGEX_ICAL_DATE, $data, $regs);
+        $datetime = date_pad($regs[1]) .'-'. date_pad($regs[2]) .'-'. date_pad($regs[3]); // Date
+        break;
+      case 'DATETIME':
+        preg_match (DATE_REGEX_ICAL_DATETIME, $data, $regs);
+        $datetime = date_pad($regs[1]) .'-'. date_pad($regs[2]) .'-'. date_pad($regs[3]); // Date
+        $datetime .= ' '. date_pad($regs[4]) .':'. date_pad($regs[5]) .':'. date_pad($regs[6]); // Time
+        $has_time = true;
+        break;
+    }
+  }
+  // If no format is specified, attempt a loose match
+  else {
+    preg_match (DATE_REGEX_LOOSE, $data, $regs);
+    $datetime = date_pad($regs[1]) .'-'. date_pad($regs[2]) .'-'. date_pad($regs[3]); // Date
+    if (isset($regs[4])) {
+      $has_time = true;
+      $datetime .= ' '.date_pad($regs[5]) .':'. date_pad($regs[6]) .':'. date_pad($regs[7]); // Time
+    }
+  }
+  
+  // Use timezone if explicitly declared
+  if (isset($properties['TZID'])) {
+    $tz = $properties['TZID'];
+  }
+  // If declared as UTC with terminating 'Z', use that timezone
+  else if (strpos($data, 'Z') !== false) {
     $tz = 'UTC';
   }
-  if (strstr($field, 'TZID=')) {
-    $tmp = explode('=', $field);
-    // Fix commonly used alternatives like US-Eastern which should be US/Eastern.
-    $tz = str_replace('-', '/', $tmp[1]);
-  }
-  $data = str_replace(array('T', 'Z'), '', $data);
-  preg_match (DATE_REGEX_LOOSE, $data, $regs);
-  if (!empty($regs[5])) {
-    $time = ' '.date_pad($regs[5]) .':'. date_pad($regs[6]) .':'. date_pad($regs[7]);
+  // Otherwise this date is floating...
+  else {
+    $tz = '';
   }
-  $items['datetime'] = $regs[1] .'-'. $regs[2] .'-'. $regs[3] . $time;
-  $items['all_day'] = empty($time) ? 1 : 0;
+  
+  $items['datetime'] = $datetime;
+  $items['all_day'] = $has_time ? false : true;
   $items['tz'] = $tz;
-  $items['granularity'] = empty($time) ? array('year', 'month', 'day') : array('year', 'month', 'day', 'hour', 'minute', 'second');
+  $items['granularity'] = $has_time ? array('year', 'month', 'day', 'hour', 'minute', 'second') : array('year', 'month', 'day');
   return $items;
 }
 
