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