| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * @file 4 * Date API elements themes and validation. 5 * This file is only included during the edit process to reduce memory usage. 6 */ 7 8 /** 9 * Implementation of hook_elements(). 10 * 11 * Parameters for date form elements, designed to have sane defaults so any 12 * or all can be omitted. 13 * 14 * Fill the element #default_value with a date in datetime format, 15 * (YYYY-MM-DD HH:MM:SS), adjusted to the proper local timezone. 16 * 17 * NOTE - Converting a date stored in the database from UTC to the local zone 18 * and converting it back to UTC before storing it is not handled by this 19 * element and must be done in pre-form and post-form processing!! 20 * 21 * The date_select element will create a collection of form elements, with a 22 * separate select or textfield for each date part. The whole collection will 23 * get re-formatted back into a date value of the requested type during validation. 24 * 25 * The date_text element will create a textfield that can contain a whole 26 * date or any part of a date as text. The user input value will be re-formatted 27 * back into a date value of the requested type during validation. 28 * 29 * The date_timezone element will create a drop-down selector to pick a 30 * timezone name. 31 * 32 * #date_timezone 33 * The local timezone to be used to create this date. 34 * 35 * #date_format 36 * A format string that describes the format and order of date parts to 37 * display in the edit form for this element. This makes it possible 38 * to show date parts in a custom order, or to leave some of them out. 39 * Be sure to add 'A' or 'a' to get an am/pm selector. Defaults to the 40 * short site default format. 41 * 42 * #date_label_position 43 * Handling option for date part labels, like 'Year', 'Month', and 'Day', 44 * can be 'above' the date part, 'within' it, or 'none', default is 'above'. 45 * The 'within' option shows the label as the first option in a select list 46 * or the default value for an empty textfield, taking up less screen space. 47 * 48 * #date_increment 49 * Increment minutes and seconds by this amount, default is 1. 50 * 51 * #date_year_range 52 * The number of years to go back and forward in a year selector, 53 * default is -3:+3 (3 back and 3 forward). 54 * 55 * #date_text_parts 56 * Array of date parts that should use textfields instead of selects 57 * i.e. array('year') will format the year as a textfield and other 58 * date parts as drop-down selects. 59 */ 60 function _date_api_elements() { 61 $date_base = array( 62 '#input' => TRUE, '#tree' => TRUE, 63 '#date_timezone' => date_default_timezone_name(), 64 '#date_format' => variable_get('date_format_short', 'm/d/Y - H:i'), 65 '#date_text_parts' => array(), 66 '#date_increment' => 1, 67 '#date_year_range' => '-3:+3', 68 '#date_label_position' => 'above', 69 ); 70 $type['date_select'] = array_merge($date_base, array( 71 '#process' => array('date_select_process'), 72 )); 73 $type['date_text'] = array_merge($date_base, array( 74 '#process' => array('date_text_process'), 75 )); 76 $type['date_timezone'] = array( 77 '#input' => TRUE, '#tree' => TRUE, 78 '#process' => array('date_timezone_process'), 79 ); 80 return $type; 81 } 82 83 /** 84 * Create a timezone form element. 85 * 86 * @param array $element 87 * @return array 88 * the timezone form element 89 */ 90 function date_timezone_process($element, $edit, $form_state, $form) { 91 $element['#tree'] = TRUE; 92 $element['timezone'] = array( 93 '#type' => 'select', 94 '#title' => theme('date_part_label_timezone', 'select', $element), 95 '#default_value' => $element['#value'], 96 '#options' => date_timezone_names($element['#required']), 97 '#weight' => $element['#weight'], 98 '#required' => $element['#required'], 99 '#theme' => 'date_select_element', 100 ); 101 if (isset($element['#element_validate'])) { 102 array_push($element['#element_validate'], 'date_timezone_validate'); 103 } 104 else { 105 $element['#element_validate'] = array('date_timezone_validate'); 106 } 107 // TODO This sometimes causes problems, do we need it? 108 //$element['#attributes'] = array('class' => 'date-timezone clear-block'); 109 return $element; 110 } 111 112 /** 113 * Text date input form. 114 * 115 * Display all or part of a date in a single textfield. 116 * 117 * The exact parts displayed in the field are those in #date_granularity. 118 * The display of each part comes from #date_format. 119 * 120 * In regular FAPI processing $element['#value'] will contain a string 121 * value before the form is submitted, and an array during submission. 122 * 123 * In regular FAPI processing $edit is empty until the form is submitted 124 * when it will contain an array. 125 * 126 * Views widget processing now receives the same values as normal FAPI 127 * processing (that was not true in Views 1). 128 * 129 */ 130 function date_text_process($element, $edit, $form_state, $form) { 131 $date = NULL; 132 $granularity = date_format_order($element['#date_format']); 133 134 // We sometimes get $edit without $edit['date'] from 135 // Views exposed filters. 136 if (!empty($edit) && is_array($edit) && !empty($edit['date'])) { 137 $datetime = date_convert_from_custom($edit['date'], $element['#date_format']); 138 $date = date_make_date($datetime, $element['#date_timezone'], DATE_DATETIME, $granularity); 139 } 140 elseif (!empty($element['#value'])) { 141 $date = date_make_date($element['#value'], $element['#date_timezone'], DATE_DATETIME, $granularity); 142 } 143 $element['#tree'] = TRUE; 144 145 $element['date']['#type'] = 'textfield'; 146 $element['date']['#weight'] = !empty($element['date']['#weight']) ? $element['date']['#weight'] : $element['#weight']; 147 $element['date']['#default_value'] = is_object($date) ? date_format_date($date , 'custom', $element['#date_format']) : ''; 148 $element['date']['#attributes'] = array('class' => (isset($element['#attributes']['class']) ? $element['#attributes']['class'] : '') .' date-date'); 149 $element['date']['#description'] = ' '. t('Format: @date', array('@date' => date_format_date(date_now(), 'custom', $element['#date_format']))); 150 151 // Keep the system from creating an error message for the sub-element. 152 // We'll set our own message on the parent element. 153 //$element['date']['#required'] = $element['#required']; 154 $element['date']['#theme'] = 'date_textfield_element'; 155 if (isset($element['#element_validate'])) { 156 array_push($element['#element_validate'], 'date_text_validate'); 157 } 158 else { 159 $element['#element_validate'] = array('date_text_validate'); 160 } 161 if (!empty($element['#force_value'])) { 162 $element['date']['#value'] = $element['date']['#default_value']; 163 } 164 return $element; 165 } 166 167 /** 168 * Flexible date/time drop-down selector. 169 * 170 * Splits date into a collection of date and time sub-elements, one 171 * for each date part. Each sub-element can be either a textfield or a 172 * select, based on the value of ['#date_settings']['text_fields']. 173 * 174 * The exact parts displayed in the field are those in #date_granularity. 175 * The display of each part comes from ['#date_settings']['format']. 176 * 177 * In regular FAPI processing $element['#value'] will contain a string 178 * value before the form is submitted, and an array during submission. 179 * 180 * In regular FAPI processing $edit is empty until the form is submitted 181 * when it will contain an array. 182 * 183 * Views widget processing now receives the same values as normal FAPI 184 * processing (that was not true in Views 1). 185 * 186 */ 187 function date_select_process($element, $edit, $form_state, $form) { 188 $date = NULL; 189 $granularity = date_format_order($element['#date_format']); 190 if (!empty($edit)) { 191 $date = date_make_date($edit, $element['#date_timezone'], DATE_ARRAY, $granularity); 192 } 193 elseif (!empty($element['#value'])) { 194 $date = date_make_date($element['#value'], $element['#date_timezone'], DATE_DATETIME, $granularity); 195 } 196 197 $element['#tree'] = TRUE; 198 date_increment_round($date, $element['#date_increment']); 199 $element += (array) date_parts_element($element, $date, $element['#date_format']); 200 201 // Store a hidden value for all date parts not in the current display. 202 $granularity = date_format_order($element['#date_format']); 203 $formats = array('year' => 'Y', 'month' => 'n', 'day' => 'j', 'hour' => 'H', 'minute' => 'i', 'second' => 's'); 204 foreach (date_nongranularity($granularity) as $field) { 205 if ($field != 'timezone') { 206 $element[$field] = array( 207 '#type' => 'value', 208 '#value' => 0, 209 ); 210 } 211 } 212 if (isset($element['#element_validate'])) { 213 array_push($element['#element_validate'], 'date_select_validate'); 214 } 215 else { 216 $element['#element_validate'] = array('date_select_validate'); 217 } 218 219 return $element; 220 } 221 222 /** 223 * Create form elements for one or more date parts. 224 * 225 * Get the order of date elements from the provided format. 226 * If the format order omits any date parts in the granularity, alter the 227 * granularity array to match the format, then flip the $order array 228 * to get the position for each element. Then iterate through the 229 * elements and create a sub-form for each part. 230 * 231 * @param array $element 232 * @param object $date 233 * @param array $granularity 234 * @param string $format 235 * @return array 236 * the form array for the submitted date parts 237 */ 238 function date_parts_element($element, $date, $format) { 239 $granularity = date_format_order($format); 240 $sub_element = array('#granularity' => $granularity); 241 $order = array_flip($granularity); 242 243 $hours_format = strpos(strtolower($element['#date_format']), 'a') ? 'g': 'G'; 244 $month_function = strpos($element['#date_format'], 'F') !== FALSE ? 'date_month_names' : 'date_month_names_abbr'; 245 $count = 0; 246 $increment = min(intval($element['#date_increment']), 1); 247 foreach ($granularity as $field) { 248 // Allow empty value as option if date is not required 249 // or if empty value was provided as a starting point. 250 $part_required = ($element['#required'] && is_object($date)) ? TRUE : FALSE; 251 $part_type = in_array($field, $element['#date_text_parts']) ? 'textfield' : 'select'; 252 $sub_element[$field] = array( 253 '#weight' => $order[$field], 254 '#required' => $element['#required'], 255 '#attributes' => array('class' => (isset($element['#attributes']['class']) ? $element['#attributes']['class'] : '') .' date-'. $field), 256 ); 257 switch ($field) { 258 case 'year': 259 $range = date_range_years($element['#date_year_range'], $date); 260 $min_year = $range[0]; 261 $max_year = $range[1]; 262 263 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, 'Y') : ''; 264 if ($part_type == 'select') { 265 $sub_element[$field]['#options'] = drupal_map_assoc(date_years($min_year, $max_year, $part_required)); 266 } 267 break; 268 case 'month': 269 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, 'n') : ''; 270 if ($part_type == 'select') { 271 $sub_element[$field]['#options'] = $month_function($part_required); 272 } 273 break; 274 case 'day': 275 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, 'j') : ''; 276 if ($part_type == 'select') { 277 $sub_element[$field]['#options'] = drupal_map_assoc(date_days($part_required)); 278 } 279 break; 280 case 'hour': 281 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, $hours_format) : ''; 282 if ($part_type == 'select') { 283 $sub_element[$field]['#options'] = drupal_map_assoc(date_hours($hours_format, $part_required)); 284 } 285 $sub_element[$field]['#prefix'] = theme('date_part_hour_prefix', $element); 286 break; 287 case 'minute': 288 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, 'i') : ''; 289 if ($part_type == 'select') { 290 $sub_element[$field]['#options'] = drupal_map_assoc(date_minutes('i', $part_required, $element['#date_increment'])); 291 } 292 $sub_element[$field]['#prefix'] = theme('date_part_minsec_prefix', $element); 293 break; 294 case 'second': 295 $sub_element[$field]['#default_value'] = is_object($date) ? date_format($date, 's') : ''; 296 if ($part_type == 'select') { 297 $sub_element[$field]['#options'] = drupal_map_assoc(date_seconds('s', $part_required, $element['#date_increment'])); 298 } 299 $sub_element[$field]['#prefix'] = theme('date_part_minsec_prefix', $element); 300 break; 301 } 302 303 // Add handling for the date part label. 304 $label = theme('date_part_label_'. $field, $part_type, $element); 305 if (in_array($field, $element['#date_text_parts'])) { 306 $sub_element[$field]['#type'] = 'textfield'; 307 $sub_element[$field]['#theme'] = 'date_textfield_element'; 308 $sub_element[$field]['#size'] = 7; 309 if ($element['#date_label_position'] == 'within') { 310 if (is_array($sub_element[$field]['#options'])) { 311 $sub_element[$field]['#options'] = array( 312 '-'. $label => '-'. $label) + $sub_element[$field]['#options']; 313 } 314 if (empty($sub_element[$field]['#default_value'])) { 315 $sub_element[$field]['#default_value'] = '-'. $label; 316 } 317 } 318 elseif ($element['#date_label_position'] != 'none') { 319 $sub_element[$field]['#title'] = $label; 320 } 321 } 322 else { 323 $sub_element[$field]['#type'] = 'select'; 324 $sub_element[$field]['#theme'] = 'date_select_element'; 325 if ($element['#date_label_position'] == 'within') { 326 $sub_element[$field]['#options'] = array( 327 '' => '-'. $label) + $sub_element[$field]['#options']; 328 } 329 elseif ($element['#date_label_position'] != 'none') { 330 $sub_element[$field]['#title'] = $label; 331 } 332 } 333 334 // Views exposed filters are treated as submitted even if not, 335 // so force the #default value in that case. Make sure we set 336 // a default that is in the option list. 337 if (!empty($element['#force_value'])) { 338 $options = $sub_element[$field]['#options']; 339 $default = !empty($sub_element[$field]['#default_value']) ? $sub_element[$field]['#default_value'] : array_shift($options); 340 $sub_element[$field]['#value'] = $default; 341 } 342 } 343 344 if (($hours_format == 'g' || $hours_format == 'h') && date_has_time($granularity)) { 345 $sub_element['ampm'] = array( 346 '#type' => 'select', 347 '#default_value' => is_object($date) ? (date_format($date, 'G') >= 12 ? 'pm' : 'am') : '', 348 '#options' => drupal_map_assoc(date_ampm()), 349 '#weight' => 8, 350 '#attributes' => array('class' => 'date-ampm'), 351 ); 352 if ($element['#date_label_position'] == 'within') { 353 $sub_element['ampm']['#options'] = array('' => '-'. theme('date_part_label_ampm', 'ampm', $element)) + $sub_element['ampm']['#options']; 354 } 355 elseif ($element['#date_label_position'] != 'none') { 356 $sub_element['ampm']['#title'] = theme('date_part_label_ampm', 'ampm', $element); 357 } 358 } 359 360 return $sub_element; 361 } 362 363 /** 364 * Validation function for date selector. 365 * 366 * When used as a Views widget, the validation step always gets triggered, 367 * even with no form submission. Before form submission $element['#value'] 368 * contains a string, after submission it contains an array. 369 * 370 */ 371 function date_select_validate($element, &$form_state) { 372 if (is_string($element['#value'])) { 373 return; 374 } 375 // Strip field labels out of the results. 376 foreach ($element['#value'] as $field => $field_value) { 377 if (substr($field_value, 0, 1) == '-') { 378 $element['#value'][$field] = ''; 379 } 380 } 381 382 $error_field = implode('][', $element['#parents']); 383 $errors = array(); 384 $label = !empty($element['#date_title']) ? $element['#date_title'] : (!empty($element['#title']) ? $element['#title'] : ''); 385 386 if (in_array('year', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['year']))) { 387 if ($element['#value']['year'] < variable_get('date_min_year', 1) || $element['#value']['year'] > variable_get('date_max_year', 4000)) { 388 $errors[] = t('The year must be a number between %min and %max.', array( 389 '%min' => variable_get('date_min_year', 1), '%max' => variable_get('date_max_year', 4000))); 390 } 391 else { 392 $year = $element['#value']['year']; 393 } 394 } 395 if (in_array('month', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['month']))) { 396 if ($element['#value']['month'] < 1 || $element['#value']['month'] > 12) { 397 $errors[] = t('The month must be a number between 1 and 12.'); 398 } 399 else { 400 $month = $element['#value']['month']; 401 } 402 } 403 if (in_array('day', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['day']))) { 404 $min = 1; 405 $max = isset($year) && isset($month) ? date_days_in_month($year, $month) : 31; 406 if ($element['#value']['day'] < $min || $element['#value']['day'] > $max) { 407 $errors[] = t('The day must be a number between !min and !max.', array('!min' => $min, '!max' => $max)); 408 } 409 } 410 if (in_array('hour', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['hour']))) { 411 $min = isset($element['#value']['ampm']) ? 1 : 0; 412 $max = isset($element['#value']['ampm']) ? 12 : 23; 413 if ($element['#value']['hour'] < $min || $element['#value']['hour'] > $max) { 414 $errors[] = t('The hour must be a number between !min and !max.', array('!min' => $min, '!max' => $max)); 415 } 416 } 417 if (in_array('minute', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['minute']))) { 418 $min = 0; 419 $max = 59; 420 if ($element['#value']['minute'] < $min || $element['#value']['minute'] > $max) { 421 $errors[] = t('The minute must be a number between !min and !max.', array('!min' => $min, '!max' => $max)); 422 } 423 } 424 if (in_array('second', $element['#granularity']) && ($element['#required'] || !empty($element['#value']['second']))) { 425 $min = 0; 426 $max = 59; 427 if ($element['#value']['second'] < $min || $element['#value']['second'] > $max) { 428 $errors[] = t('The second must be a number between !min and !max.', array('!min' => $min, '!max' => $max)); 429 } 430 } 431 if (isset($element['#value']['ampm'])) { 432 if ($element['#value']['ampm'] == 'pm' && $element['#value']['hour'] < 12) { 433 $element['#value']['hour'] += 12; 434 } 435 elseif ($element['#value']['ampm'] == 'am' && $element['#value']['hour'] == 12) { 436 $element['#value']['hour'] -= 12; 437 } 438 } 439 $value = date_select_input_value($element); 440 if (empty($value) && empty($errors) && $element['#required']) { 441 $errors[] = t('A valid value is required.'); 442 } 443 if (!empty($errors)) { 444 array_unshift($errors, t('Field %field has errors.', array('%field' => $label))); 445 form_set_error($error_field, implode(' ', $errors)); 446 } 447 // If there are no errors and the value is valid, set it. 448 if (empty($errors) && !empty($value)) { 449 form_set_value($element, $value, $form_state); 450 } 451 else { 452 form_set_value($element, NULL, $form_state); 453 } 454 } 455 456 /** 457 * Helper function for extracting a date value out of user input. 458 */ 459 function date_select_input_value($element) { 460 $granularity = date_format_order($element['#date_format']); 461 if (date_is_valid($element['#value'], DATE_ARRAY, $granularity)) { 462 // Use fuzzy_datetime here to be sure year-only dates 463 // aren't inadvertantly shifted to the wrong year by trying 464 // to save '2009-00-00 00:00:00'. 465 return date_fuzzy_datetime(date_convert($element['#value'], DATE_ARRAY, DATE_DATETIME)); 466 } 467 return NULL; 468 } 469 470 /** 471 * Validation for text input. 472 * 473 * When used as a Views widget, the validation step always gets triggered, 474 * even with no form submission. Before form submission $element['#value'] 475 * contains a string, after submission it contains an array. 476 * 477 */ 478 function date_text_validate($element, &$form_state) { 479 if (is_string($element['#value'])) { 480 return; 481 } 482 $parents = $element['#parents']; 483 $label = !empty($element['#date_title']) ? $element['#date_title'] : (!empty($element['#title']) ? $element['#title'] : ''); 484 $value = date_text_input_value($element); 485 486 if (empty($value) && !empty($element['#required'])) { 487 form_error($element, t('A valid date is required for %title.', array('%title' => $label))); 488 } 489 elseif (empty($value) && !empty($element['#value']['date'])) { 490 form_error($element, t('%title is invalid.', array('%title' => $label))); 491 } 492 elseif (!empty($value)) { 493 form_set_value($element, $value, $form_state); 494 } 495 } 496 497 /** 498 * Helper function for extracting a date value out of user input. 499 */ 500 function date_text_input_value($element) { 501 $form_values = $element['#value']; 502 $granularity = date_format_order($element['#date_format']); 503 $input = $form_values['date']; 504 if (!$element['#required'] && trim($input) == '') return NULL; 505 506 $value = date_limit_value(date_convert_from_custom($input, $element['#date_format']), $granularity); 507 508 // If it creates a valid date, use it. 509 if (date_is_valid($value, DATE_DATETIME, $granularity)) { 510 return $value; 511 } 512 // TODO come back and try to find a way to use strtotime to guess 513 // a valid value. Previous attempts to do it were too forgiving and 514 // invalid input was just silently converted to 'now'. 515 // See http://drupal.org/node/265076. 516 517 return NULL; 518 } 519 520 /** 521 * Validation for timezone input 522 * 523 * Move the timezone value from the nested field back to the original field. 524 */ 525 function date_timezone_validate($element, &$form_state) { 526 form_set_value($element, $element['#value']['timezone'], $form_state); 527 } 528 529 /** 530 * Convert a date input in a custom format to a standard date type 531 * 532 * Handles conversion of translated month names (i.e. turns t('Mar') or 533 * t('March') into 3). Also properly handles dates input in European style 534 * short formats, like DD/MM/YYYY. Works by parsing the format string 535 * to create a regex that can be used on the input value. 536 * 537 * The original code to do this was created by Yves Chedemois (yched). 538 * 539 * @param string $date 540 * a date value 541 * @param string $format 542 * a date format string that describes the format of the input value 543 * @return mixed 544 * input value converted to a DATE_DATETIME value 545 */ 546 function date_convert_from_custom($date, $format) { 547 $array = date_format_patterns(); 548 foreach ($array as $key => $value) { 549 $patterns[] = "`(^|[^\\\\\\\\])". $key ."`"; // the letter with no preceding '\' 550 $repl1[] = '$1}(.)'; // a single character 551 $repl2[] = '$1}('. $value .')'; // the 552 } 553 $patterns[] = "`\\\\\\\\([". implode(array_keys($array)) ."])`"; 554 $repl1[] = '$1}'; 555 $repl2[] = '$1}'; 556 557 $format_regexp = preg_quote($format); 558 559 // extract letters 560 $regex1 = preg_replace($patterns, $repl1, $format_regexp, 1); 561 $regex1 = str_replace('A', '(.)', $regex1); 562 $regex1 = str_replace('a', '(.)', $regex1); 563 preg_match('`^'. $regex1 .'$`', stripslashes($format), $letters); 564 array_shift($letters); 565 566 // extract values 567 $regex2 = preg_replace($patterns, $repl2, $format_regexp, 1); 568 $regex2 = str_replace('A', '(AM|PM)', $regex2); 569 $regex2 = str_replace('a', '(am|pm)', $regex2); 570 preg_match('`^'. $regex2 .'$`', $date, $values); 571 array_shift($values); 572 573 // if we did not find all the values for the patterns in the format, abort 574 if (count($letters) != count($values)) { 575 return NULL; 576 } 577 $final_date = array('hour' => 0, 'minute' => 0, 'second' => 0, 578 'month' => 0, 'day' => 0, 'year' => 0); 579 foreach ($letters as $i => $letter) { 580 $value = $values[$i]; 581 switch ($letter) { 582 case 'd': 583 case 'j': 584 $final_date['day'] = intval($value); 585 break; 586 case 'n': 587 case 'm': 588 $final_date['month'] = intval($value); 589 break; 590 case 'F': 591 $array_month_long = array_flip(date_month_names()); 592 $final_date['month'] = $array_month_long[$value]; 593 break; 594 case 'M': 595 $array_month = array_flip(date_month_names_abbr()); 596 $final_date['month'] = $array_month[$value]; 597 break; 598 case 'Y': 599 case 'y': 600 $year = $value; 601 // if no century, we add the current one ("06" => "2006") 602 $final_date['year'] = str_pad($year, 4, substr(date("Y"), 0, 2), STR_PAD_LEFT); 603 break; 604 case 'a': 605 case 'A': 606 $ampm = strtolower($value); 607 break; 608 case 'g': 609 case 'h': 610 case 'G': 611 case 'H': 612 $final_date['hour'] = intval($value); 613 break; 614 case 'i': 615 $final_date['minute'] = intval($value); 616 break; 617 case 's': 618 $final_date['second'] = intval($value); 619 break; 620 case 'U': 621 return date_convert($value, DATE_UNIX, DATE_DATETIME); 622 break; 623 } 624 } 625 if (isset($ampm) && $ampm == 'pm' && $final_date['hour'] < 12) { 626 $final_date['hour'] += 12; 627 } 628 elseif (isset($ampm) && $ampm == 'am' && $final_date['hour'] == 12) { 629 $final_date['hour'] -= 12; 630 } 631 // Don't test for valid date, we might use this to extract 632 // incomplete date part info from user input. 633 return date_convert($final_date, DATE_ARRAY, DATE_DATETIME); 634 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |