| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: date_php4_calc.inc,v 1.4.4.2 2008/08/30 13:57:39 karens Exp $ 3 /** 4 * Calculates and manipulates dates with no reliance on 32-bit system 5 * timestamps, to work on dates before 1970 and after 2038. 6 * 7 * This file must be included whenever these functions are used, it is 8 * not automatically available. 9 * 10 * The functions below were derived from code obtained from 11 * http://pear.php.net/package/Date/Calc.php, licensed as follows: 12 * 13 * Copyright (c) 1999-2006 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted under the terms of the BSD License. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 define('DATE_CALC_FORMAT', '%Y-%m-%d'); 33 34 // Some functions from the low level library are needed here, make sure 35 // they are available. 36 require_once('./'. drupal_get_path('module', 'date_php4') .'/date_php4_lib.inc'); 37 38 /** 39 * The default value for each method's $format parameter 40 * 41 * The default is '%Y%m%d'. To override this default, define 42 * this constant before including Calc.php. 43 * 44 * @since Constant available since Release 1.4.4 45 */ 46 /** 47 * Formats the date in the given format, much like strfmt() 48 * 49 * This function is used to alleviate the problem with 32-bit numbers for 50 * dates pre 1970 or post 2038, as strfmt() has on most systems. 51 * Most of the formatting options are compatible. 52 * 53 * Formatting options: 54 * <pre> 55 * %a abbreviated weekday name (Sun, Mon, Tue) 56 * %A full weekday name (Sunday, Monday, Tuesday) 57 * %b abbreviated month name (Jan, Feb, Mar) 58 * %B full month name (January, February, March) 59 * %d day of month (range 00 to 31) 60 * %e day of month, single digit (range 0 to 31) 61 * %E number of days since unspecified epoch (integer) 62 * (%E is useful for passing a date in a URL as 63 * an integer value. Then simply use 64 * date_calc_days_to_date() to convert back to a date.) 65 * %j day of year (range 001 to 366) 66 * %m month as decimal number (range 1 to 12) 67 * %n newline character (\n) 68 * %t tab character (\t) 69 * %w weekday as decimal (0 = Sunday) 70 * %U week number of current year, first sunday as first week 71 * %y year as decimal (range 00 to 99) 72 * %Y year as decimal including century (range 0000 to 9999) 73 * %% literal '%' 74 * </pre> 75 * 76 * @param int $day 77 * The day of the month. 78 * @param int $month 79 * The month. 80 * @param int $year 81 * The 4 digit year. Do not add leading 0's for years prior to 1000. 82 * @param string $format 83 * The format string. 84 * 85 * @return string 86 * The date in the desired format. 87 */ 88 function date_calc_format($day, $month, $year, $format = DATE_CALC_FORMAT) { 89 if (!date_calc_is_valid($day, $month, $year)) { 90 $year = date_calc_date_now('%Y'); 91 $month = date_calc_date_now('%m'); 92 $day = date_calc_date_now('%d'); 93 } 94 $output = ''; 95 for ($strpos = 0; $strpos < strlen($format); $strpos++) { 96 $char = substr($format, $strpos, 1); 97 if ($char == '%') { 98 $nextchar = substr($format, $strpos + 1, 1); 99 switch ($nextchar) { 100 case 'a': 101 $output .= date_calc_get_weekday_abbrname($day, $month, $year); 102 break; 103 case 'A': 104 $output .= date_calc_get_weekday_fullname($day, $month, $year); 105 break; 106 case 'b': 107 $output .= date_calc_get_month_abbrname($month); 108 break; 109 case 'B': 110 $output .= date_calc_get_month_fullname($month); 111 break; 112 case 'd': 113 $output .= date_pad($day); 114 break; 115 case 'e': 116 $output .= $day; 117 break; 118 case 'E': 119 $output .= date_calc_date_to_days($day, $month, $year); 120 break; 121 case 'j': 122 $output .= date_calc_julian_date($day, $month, $year); 123 break; 124 case 'm': 125 $output .= date_pad($month); 126 break; 127 case 'n': 128 $output .= "\n"; 129 break; 130 case 't': 131 $output .= "\t"; 132 break; 133 case 'w': 134 $output .= date_dow($day, $month, $year); 135 break; 136 case 'U': 137 $output .= date_calc_week_of_year($day, $month, $year); 138 break; 139 case 'y': 140 $output .= substr(date_pad($year, 4), 2, 2); 141 break; 142 case 'Y': 143 $output .= date_pad($year, 4); 144 break; 145 case '%': 146 $output .= '%'; 147 break; 148 default: 149 $output .= $char . $nextchar; 150 } 151 $strpos++; 152 } 153 else { 154 $output .= $char; 155 } 156 } 157 return $output; 158 } 159 160 /** 161 * Returns true for valid date, false for invalid date. 162 * Renamed this function because we already have a similar function that 163 * expects a full date as a parameter. 164 * 165 * @param int $day 166 * the day of the month 167 * @param int $month 168 * the month 169 * @param int $year 170 * the year, using 2005, not 05. Do not add leading 0's for years prior to 1000. 171 * 172 * @return boolean 173 */ 174 function date_calc_is_valid($day, $month, $year) { 175 if ($year > variable_get('date_max_year', 4000) || $year < variable_get('date_min_year', 1)) { 176 return false; 177 } 178 if (!checkdate($month, $day, $year)) { 179 // Checkdate won't work on very old dates in PHP 4, need more testing. 180 if (!date_gmmktime(0, 0, 0, $month, $day, $year)) { 181 return false; 182 } 183 } 184 return true; 185 } 186 187 /** 188 * Converts a date to number of days since a distant unspecified epoch 189 * 190 * @param int $day 191 * The day of the month. 192 * @param int $month 193 * The month. 194 * @param int $year 195 * The 4 digit year. Do not add leading 0's for years prior to 1000. 196 * 197 * @return integer 198 * The number of days since the date_calc epoch. 199 */ 200 function date_calc_date_to_days($day, $month, $year) { 201 $century = (int)substr($year, 0, 2); 202 $year = (int)substr($year, 2, 2); 203 if ($month > 2) { 204 $month -= 3; 205 } 206 else { 207 $month += 9; 208 if ($year) { 209 $year--; 210 } 211 else { 212 $year = 99; 213 $century --; 214 } 215 } 216 return (floor((146097 * $century) / 4 ) + 217 floor((1461 * $year) / 4 ) + 218 floor((153 * $month + 2) / 5 ) + 219 $day + 1721119); 220 } 221 222 /** 223 * Converts number of days to a distant unspecified epoch 224 * 225 * @param int $days 226 * The number of days since the date_calc epoch. 227 * @param string $format 228 * The string indicating how to format the output. 229 * 230 * @return string 231 * The date in the desired format. 232 */ 233 function date_calc_days_to_date($days, $format = DATE_CALC_FORMAT) { 234 $days -= 1721119; 235 $century = floor((4 * $days - 1) / 146097); 236 $days = floor(4 * $days - 1 - 146097 * $century); 237 $day = floor($days / 4); 238 239 $year = floor((4 * $day + 3) / 1461); 240 $day = floor(4 * $day + 3 - 1461 * $year); 241 $day = floor(($day + 4) / 4); 242 243 $month = floor((5 * $day - 3) / 153); 244 $day = floor(5 * $day - 3 - 153 * $month); 245 $day = floor(($day + 5) / 5); 246 247 if ($month < 10) { 248 $month +=3; 249 } 250 else { 251 $month -=9; 252 if ($year++ == 99) { 253 $year = 0; 254 $century++; 255 } 256 } 257 $century = date_pad($century); 258 $year = date_pad($year); 259 return date_calc_format($day, $month, $century . $year, $format); 260 } 261 262 /** 263 * Converts from Gregorian Year-Month-Day to ISO Year-WeekNumber-WeekDay 264 * 265 * Uses ISO 8601 definitions. Algorithm by Rick McCarty, 1999 at 266 * http://personal.ecu.edu/mccartyr/ISOwdALG.txt . 267 * Transcribed to PHP by Jesus M. Castagnetto. 268 * 269 * @param int $day 270 * The day of the month. 271 * @param int $month 272 * The month. 273 * @param int $year 274 * The 4 digit year. Do not add leading 0's for years prior to 1000. 275 * 276 * @return string 277 * The date in ISO Year-WeekNumber-WeekDay format. 278 */ 279 function date_calc_gregorian_to_ISO($day, $month, $year) { 280 $mnth = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334); 281 $y_isleap = date_is_leap_year($year); 282 $y_1_isleap = date_is_leap_year($year - 1); 283 $day_of_year_number = $day + $mnth[$month - 1]; 284 if ($y_isleap && $month > 2) { 285 $day_of_year_number++; 286 } 287 // find Jan 1 weekday (monday = 1, sunday = 7) 288 $yy = ($year - 1) % 100; 289 $c = ($year - 1) - $yy; 290 $g = $yy + intval($yy / 4); 291 $jan1_weekday = 1 + intval((((($c / 100) % 4) * 5) + $g) % 7); 292 // weekday for year-month-day 293 $h = $day_of_year_number + ($jan1_weekday - 1); 294 $weekday = 1 + intval(($h - 1) % 7); 295 // find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 296 if ($day_of_year_number <= (8 - $jan1_weekday) && $jan1_weekday > 4) { 297 $yearnumber = $year - 1; 298 if ($jan1_weekday == 5 || ($jan1_weekday == 6 && $y_1_isleap)) { 299 $weeknumber = 53; 300 } 301 else { 302 $weeknumber = 52; 303 } 304 } 305 else { 306 $yearnumber = $year; 307 } 308 // find if Y M D falls in YearNumber Y+1, WeekNumber 1 309 if ($yearnumber == $year) { 310 if ($y_isleap) { 311 $i = 366; 312 } 313 else { 314 $i = 365; 315 } 316 if (($i - $day_of_year_number) < (4 - $weekday)) { 317 $yearnumber++; 318 $weeknumber = 1; 319 } 320 } 321 // find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 322 if ($yearnumber == $year) { 323 $j = $day_of_year_number + (7 - $weekday) + ($jan1_weekday - 1); 324 $weeknumber = intval($j / 7); 325 if ($jan1_weekday > 4) { 326 $weeknumber--; 327 } 328 } 329 // put it all together 330 if ($weeknumber < 10) { 331 $weeknumber = '0'. $weeknumber; 332 } 333 return $yearnumber .'-'. $weeknumber .'-'. $weekday; 334 } 335 336 /** 337 * Determines julian date of the given season 338 * 339 * Adapted from previous work in Java by James Mark Hamilton. 340 * 341 * @param string $season 342 * The season to get the date for: 343 * VERNALEQUINOX, SUMMERSOLSTICE, AUTUMNALEQUINOX, or WINTERSOLSTICE. 344 * @param string $year 345 * The year in four digit format. Must be between -1000BC and 3000AD. 346 * 347 * @return float 348 * The julian date the season starts on. 349 * 350 * @author James Mark Hamilton <mhamilton@qwest.net> 351 * @author Robert Butler <rob@maxwellcreek.org> 352 */ 353 function date_calc_date_season($season, $year = 0) { 354 if ($year == '') { 355 $year = date_calc_get_year(); 356 } 357 if (($year >= -1000) && ($year <= 1000)) { 358 $y = $year / 1000.0; 359 switch ($season) { 360 case 'VERNALEQUINOX': 361 $date_calc_julian_date = (((((((-0.00071 * $y) - 0.00111) * $y) + 0.06134) * $y) + 365242.1374) * $y) + 1721139.29189; 362 break; 363 case 'SUMMERSOLSTICE': 364 $date_calc_julian_date = (((((((0.00025 * $y) + 0.00907) * $y) - 0.05323) * $y) + 365241.72562) * $y) + 1721233.25401; 365 break; 366 case 'AUTUMNALEQUINOX': 367 $date_calc_julian_date = (((((((0.00074 * $y) - 0.00297) * $y) - 0.11677) * $y) + 365242.49558) * $y) + 1721325.70455; 368 break; 369 case 'WINTERSOLSTICE': 370 default: 371 $date_calc_julian_date = (((((((-0.00006 * $y) - 0.00933) * $y) - 0.00769) * $y) + 365242.88257) * $y) + 1721414.39987; 372 } 373 } 374 elseif (($year > 1000) && ($year <= 3000)) { 375 $y = ($year - 2000) / 1000; 376 switch ($season) { 377 case 'VERNALEQUINOX': 378 $date_calc_julian_date = (((((((-0.00057 * $y) - 0.00411) * $y) + 0.05169) * $y) + 365242.37404) * $y) + 2451623.80984; 379 break; 380 case 'SUMMERSOLSTICE': 381 $date_calc_julian_date = (((((((-0.0003 * $y) + 0.00888) * $y) + 0.00325) * $y) + 365241.62603) * $y) + 2451716.56767; 382 break; 383 case 'AUTUMNALEQUINOX': 384 $date_calc_julian_date = (((((((0.00078 * $y) + 0.00337) * $y) - 0.11575) * $y) + 365242.01767) * $y) + 2451810.21715; 385 break; 386 case 'WINTERSOLSTICE': 387 default: 388 $date_calc_julian_date = (((((((0.00032 * $y) - 0.00823) * $y) - 0.06223) * $y) + 365242.74049) * $y) + 2451900.05952; 389 } 390 } 391 return $date_calc_julian_date; 392 } 393 394 /** 395 * Returns the current local date. 396 * 397 * NOTE: This function retrieves the local date using strftime(), 398 * which may or may not be 32-bit safe on your system. 399 * 400 * @param string $format 401 * The string indicating how to format the output. 402 * 403 * @return string 404 * The current date in the specified format. 405 */ 406 function date_calc_date_now($format = DATE_CALC_FORMAT) { 407 return strftime($format, time()); 408 } 409 410 /** 411 * Returns the current local year in format CCYY. 412 * 413 * @param int $days 414 * An integer calculated by date_calc_date_to_days(). 415 * 416 * @return string 417 * The current year in four digit format. 418 */ 419 function date_calc_get_year() { 420 return date_calc_date_now('%Y'); 421 } 422 423 /** 424 * Returns the current local month in format MM 425 * 426 * @param int $days 427 * An integer calculated by date_calc_date_to_days(). 428 * 429 * @return string 430 * The current month in two digit format. 431 */ 432 function date_calc_get_month() { 433 return date_calc_date_now('%m'); 434 } 435 436 /** 437 * Returns the current local day in format DD 438 * 439 * @param int $days 440 * An integer calculated by date_calc_date_to_days(). 441 * 442 * @return string 443 * The current day of the month in two digit format. 444 */ 445 function date_calc_get_day() { 446 return date_calc_date_now('%d'); 447 } 448 449 /** 450 * Returns number of days since 31 December of year before given date. 451 * 452 * @param int $day 453 * The day of the month. 454 * @param int $month 455 * The month. 456 * @param int $year 457 * The 4 digit year. Do not add leading 0's for years prior to 1000. 458 * 459 * @return int 460 * The julian date for the date. 461 */ 462 function date_calc_julian_date($day = 0, $month = 0, $year = 0) { 463 if (empty($year)) { 464 $year = date_calc_get_year(); 465 } 466 if (empty($month)) { 467 $month = date_calc_get_month(); 468 } 469 if (empty($day)) { 470 $day = date_calc_get_day(); 471 } 472 $days = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334); 473 $julian = ($days[$month - 1] + $day); 474 if ($month > 2 && date_is_leap_year($year)) { 475 $julian++; 476 } 477 return $julian; 478 } 479 480 /** 481 * Returns the full weekday name for the given date 482 * 483 * @param int $day 484 * The day of the month. 485 * @param int $month 486 * The month. 487 * @param int $year 488 * The 4 digit year. Do not add leading 0's for years prior to 1000. 489 * 490 * @return string 491 * The full name of the day of the week/ 492 */ 493 function date_calc_get_weekday_fullname($day = 0, $month = 0, $year = 0) { 494 if (empty($year)) { 495 $year = date_calc_get_year(); 496 } 497 if (empty($month)) { 498 $month = date_calc_get_month(); 499 } 500 if (empty($day)) { 501 $day = date_calc_get_day(); 502 } 503 $weekday_names = date_week_days(); 504 $weekday = date_dow($day, $month, $year); 505 return $weekday_names[$weekday]; 506 } 507 508 /** 509 * Returns the abbreviated weekday name for the given date. 510 * 511 * @param int $day 512 * The day of the month. 513 * @param int $month 514 * The month. 515 * @param int $year 516 * The year. Use the complete year instead of the abbreviated version. 517 * E.g. use 2005, not 05. Do not add leading 0's for years prior to 1000. 518 * @param int $length 519 * The length of abbreviation. 520 * 521 * @return string 522 * The abbreviated name of the day of the week. 523 */ 524 function date_calc_get_weekday_abbrname($day = 0, $month = 0, $year = 0) { 525 if (empty($year)) { 526 $year = date_calc_get_year(); 527 } 528 if (empty($month)) { 529 $month = date_calc_get_month(); 530 } 531 if (empty($day)) { 532 $day = date_calc_get_day(); 533 } 534 $weekday_names = date_week_days_abbr(); 535 $weekday = date_dow($day, $month, $year); 536 return $weekday_names[$weekday]; 537 } 538 539 /** 540 * Returns the full month name for the given month. 541 * 542 * @param int $month 543 * The month. 544 * 545 * @return string 546 * The full name of the month. 547 */ 548 function date_calc_get_month_fullname($month) { 549 $month = (int)$month; 550 if (empty($month)) { 551 $month = (int)date_calc_get_month(); 552 } 553 $month_names = date_month_names(); 554 return $month_names[$month]; 555 } 556 557 /** 558 * Returns the abbreviated month name for the given month. 559 * 560 * @param int $month 561 * The month. 562 * @param int $length 563 * The length of abbreviation. 564 * 565 * @return string 566 * The abbreviated name of the month. 567 */ 568 function date_calc_get_month_abbrname($month, $length = 3) { 569 $month = (int)$month; 570 if (empty($month)) { 571 $month = date_calc_get_month(); 572 } 573 return drupal_substr(date_calc_get_month_fullname($month), 0, $length); 574 } 575 576 /** 577 * Returns the numeric month from the month name or an abreviation 578 * Both August and Aug would return 8. 579 * 580 * @param string $month 581 * The name of the month to examine. Case insensitive. 582 * 583 * @return integer 584 * The month's number. 585 */ 586 function date_calc_get_month_from_fullname($month) { 587 $month = strtolower($month); 588 $months = date_month_names(); 589 while (list($id, $name) = each($months)) { 590 if (ereg($month, strtolower($name))) { 591 return $id; 592 } 593 } 594 return 0; 595 } 596 597 /** 598 * Returns week of the year, first Sunday is first day of first week. 599 * 600 * @param int $day 601 * The day of the month. 602 * @param int $month 603 * The month. 604 * @param int $year 605 * The 4 digit year. Do not add leading 0's for years prior to 1000. 606 * 607 * @return int 608 * The number of the week in the year. 609 */ 610 function date_calc_week_of_year($day = 0, $month = 0, $year = 0) { 611 if (empty($year)) { 612 $year = date_calc_get_year(); 613 } 614 if (empty($month)) { 615 $month = date_calc_get_month(); 616 } 617 if (empty($day)) { 618 $day = date_calc_get_day(); 619 } 620 $iso = date_calc_gregorian_to_ISO($day, $month, $year); 621 $parts = explode('-', $iso); 622 $week_number = intval($parts[1]); 623 return $week_number; 624 } 625 626 /** 627 * Returns quarter of the year for given date. 628 * 629 * @param int $day 630 * The day of the month. 631 * @param int $month 632 * The month. 633 * @param int $year 634 * 635 * @return int 636 * The number of the quarter in the year. 637 */ 638 function date_calc_quarter_of_year($day = 0, $month = 0, $year = 0) { 639 if (empty($year)) { 640 $year = date_calc_get_year(); 641 } 642 if (empty($month)) { 643 $month = date_calc_get_month(); 644 } 645 if (empty($day)) { 646 $day = date_calc_get_day(); 647 } 648 $year_quarter = intval(($month - 1) / 3 + 1); 649 return $year_quarter; 650 } 651 652 /** 653 * Find the number of days in the given month. 654 * 655 * @param int $month 656 * The month. 657 * @param int $year 658 * The 4 digit year. Do not add leading 0's for years prior to 1000. 659 * 660 * @return int 661 * The number of days the month has. 662 */ 663 function date_calc_days_in_month($month = 0, $year = 0) { 664 if (empty($year)) { 665 $year = date_calc_get_year(); 666 } 667 if (empty($month)) { 668 $month = date_calc_get_month(); 669 } 670 if ($year == 1582 && $month == 10) { 671 return 21; // October 1582 only had 1st-4th and 15th-31st 672 } 673 if ($month == 2) { 674 if (date_is_leap_year($year)) { 675 return 29; 676 } 677 else { 678 return 28; 679 } 680 } 681 elseif ($month == 4 or $month == 6 or $month == 9 or $month == 11) { 682 return 30; 683 } 684 else { 685 return 31; 686 } 687 } 688 689 /** 690 * Returns the number of rows on a calendar month. Useful for determining 691 * the number of rows when displaying a typical month calendar. 692 * 693 * @param int $month 694 * The month. 695 * @param int $year 696 * The 4 digit year. Do not add leading 0's for years prior to 1000. 697 * 698 * @return int 699 * The number of weeks the month has. 700 */ 701 function date_calc_weeks_in_month($month = 0, $year = 0) { 702 if (empty($year)) { 703 $year = date_calc_get_year(); 704 } 705 if (empty($month)) { 706 $month = date_calc_get_month(); 707 } 708 $FDOM = date_calc_first_of_month_weekday($month, $year); 709 if (variable_get('date_first_day', 1)==1 && $FDOM==0) { 710 $first_week_days = 7 - $FDOM + variable_get('date_first_day', 1); 711 $weeks = 1; 712 } 713 elseif (variable_get('date_first_day', 1)==0 && $FDOM == 6) { 714 $first_week_days = 7 - $FDOM + variable_get('date_first_day', 1); 715 $weeks = 1; 716 } 717 else { 718 $first_week_days = variable_get('date_first_day', 1) - $FDOM; 719 $weeks = 0; 720 } 721 $first_week_days %= 7; 722 return ceil((date_calc_days_in_month($month, $year) 723 - $first_week_days) / 7) + $weeks; 724 } 725 726 /** 727 * Return an array with days in week. 728 * 729 * @param int $day 730 * The day of the month. 731 * @param int $month 732 * The month. 733 * @param int $year 734 * The 4 digit year. Do not add leading 0's for years prior to 1000. 735 * @param string $format 736 * The string indicating how to format the output. 737 * 738 * @return array 739 * $week[$weekday]. 740 */ 741 function date_calc_get_calendar_week($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 742 if (empty($year)) { 743 $year = date_calc_get_year(); 744 } 745 if (empty($month)) { 746 $month = date_calc_get_month(); 747 } 748 if (empty($day)) { 749 $day = date_calc_get_day(); 750 } 751 $week_array = array(); 752 // date for the column of week 753 $curr_day = date_calc_begin_of_week($day, $month, $year, '%E'); 754 for ($counter = 0; $counter <= 6; $counter++) { 755 $week_array[$counter] = date_calc_days_to_date($curr_day, $format); 756 $curr_day++; 757 } 758 return $week_array; 759 } 760 761 /** 762 * Return a set of arrays to construct a calendar month for the given date. 763 * 764 * @param int $month 765 * The month. 766 * @param int $year 767 * The 4 digit year. Do not add leading 0's for years prior to 1000. 768 * @param string $format 769 * The string indicating how to format the output. 770 * 771 * @return array 772 * $month[$row][$col]. 773 */ 774 function date_calc_get_calendar_month($month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 775 if (empty($year)) { 776 $year = date_calc_get_year(); 777 } 778 if (empty($month)) { 779 $month = date_calc_get_month(); 780 } 781 $month_array = array(); 782 // date for the first row, first column of calendar month 783 if (variable_get('date_first_day', 1) == 1) { 784 if (date_calc_first_of_month_weekday($month, $year) == 0) { 785 $curr_day = date_calc_date_to_days('01', $month, $year) - 6; 786 } 787 else { 788 $curr_day = date_calc_date_to_days('01', $month, $year) 789 - date_calc_first_of_month_weekday($month, $year) + 1; 790 } 791 } 792 else { 793 $curr_day = (date_calc_date_to_days('01', $month, $year) 794 - date_calc_first_of_month_weekday($month, $year)); 795 } 796 // number of days in this month 797 $date_calc_days_in_month = date_calc_days_in_month($month, $year); 798 $date_calc_weeks_in_month = date_calc_weeks_in_month($month, $year); 799 for ($row_counter = 0; $row_counter < $date_calc_weeks_in_month; $row_counter++) { 800 for ($column_counter = 0; $column_counter <= 6; $column_counter++) { 801 $month_array[$row_counter][$column_counter] = 802 date_calc_days_to_date($curr_day , $format); 803 $curr_day++; 804 } 805 } 806 return $month_array; 807 } 808 809 /** 810 * Return a set of arrays to construct a calendar year for the given date 811 * 812 * @param int $year 813 * The 4 digit year. Do not add leading 0's for years prior to 1000. 814 * @param string $format 815 * The string indicating how to format the output. 816 * 817 * @return array $year[$month][$row][$col] 818 */ 819 function date_calc_get_calendar_year($year = 0, $format = DATE_CALC_FORMAT) { 820 if (empty($year)) { 821 $year = date_calc_get_year(); 822 } 823 $year_array = array(); 824 for ($curr_month = 0; $curr_month <= 11; $curr_month++) { 825 $year_array[$curr_month] = 826 date_calc_get_calendar_month($curr_month + 1, 827 $year, $format); 828 } 829 return $year_array; 830 } 831 832 /** 833 * Returns date of day before given date. 834 * 835 * @param int $day 836 * The day of the month. 837 * @param int $month 838 * The month. 839 * @param int $year 840 * The 4 digit year. Do not add leading 0's for years prior to 1000. 841 * @param string $format 842 * The string indicating how to format the output. 843 * 844 * @return string 845 * The date in the desired format. 846 */ 847 function date_calc_prev_day($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 848 if (empty($year)) { 849 $year = date_calc_get_year(); 850 } 851 if (empty($month)) { 852 $month = date_calc_get_month(); 853 } 854 if (empty($day)) { 855 $day = date_calc_get_day(); 856 } 857 $days = date_calc_date_to_days($day, $month, $year); 858 return date_calc_days_to_date($days - 1, $format); 859 } 860 861 /** 862 * Returns date of day after given date 863 * 864 * @param int $day 865 * The day of the month. 866 * @param int $month 867 * The month. 868 * @param int $year 869 * The 4 digit year. Do not add leading 0's for years prior to 1000. 870 * @param string $format 871 * The string indicating how to format the output. 872 * 873 * @return string 874 * The date in the desired format. 875 */ 876 function date_calc_next_day($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 877 if (empty($year)) { 878 $year = date_calc_get_year(); 879 } 880 if (empty($month)) { 881 $month = date_calc_get_month(); 882 } 883 if (empty($day)) { 884 $day = date_calc_get_day(); 885 } 886 $days = date_calc_date_to_days($day, $month, $year); 887 return date_calc_days_to_date($days + 1, $format); 888 } 889 890 /** 891 * Returns date of the previous weekday, skipping from Monday to Friday 892 * 893 * @param int $day 894 * The day of the month. 895 * @param int $month 896 * The month. 897 * @param int $year 898 * The 4 digit year. Do not add leading 0's for years prior to 1000. 899 * @param string $format 900 * The string indicating how to format the output. 901 * 902 * @return string 903 * The date in the desired format. 904 */ 905 function date_calc_prev_weekday($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 906 if (empty($year)) { 907 $year = date_calc_get_year(); 908 } 909 if (empty($month)) { 910 $month = date_calc_get_month(); 911 } 912 if (empty($day)) { 913 $day = date_calc_get_day(); 914 } 915 $days = date_calc_date_to_days($day, $month, $year); 916 if (date_dow($day, $month, $year) == 1) { 917 $days -= 3; 918 } 919 elseif (date_dow($day, $month, $year) == 0) { 920 $days -= 2; 921 } 922 else { 923 $days -= 1; 924 } 925 return date_calc_days_to_date($days, $format); 926 } 927 928 /** 929 * Returns date of the next weekday of given date, skipping from 930 * Friday to Monday. 931 * 932 * @param int $day 933 * The day of the month. 934 * @param int $month 935 * The month. 936 * @param int $year 937 * The 4 digit year. Do not add leading 0's for years prior to 1000. 938 * @param string $format 939 * The string indicating how to format the output. 940 * 941 * @return string 942 * The date in the desired format. 943 */ 944 function date_calc_next_weekday($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 945 if (empty($year)) { 946 $year = date_calc_get_year(); 947 } 948 if (empty($month)) { 949 $month = date_calc_get_month(); 950 } 951 if (empty($day)) { 952 $day = date_calc_get_day(); 953 } 954 $days = date_calc_date_to_days($day, $month, $year); 955 if (date_dow($day, $month, $year) == 5) { 956 $days += 3; 957 } 958 elseif (date_dow($day, $month, $year) == 6) { 959 $days += 2; 960 } 961 else { 962 $days += 1; 963 } 964 return date_calc_days_to_date($days, $format); 965 } 966 967 /** 968 * Returns date of the previous specific day of the week 969 * from the given date. 970 * 971 * @param int 972 * Day of week, 0=Sunday. 973 * @param int $day 974 * The day of the month. 975 * @param int $month 976 * The month. 977 * @param int $year 978 * The 4 digit year. Do not add leading 0's for years prior to 1000. 979 * @param bool $on_or_before 980 * If true and days are same, returns current day. 981 * @param string $format 982 * The string indicating how to format the output. 983 * 984 * @return string 985 * The date in the desired format. 986 */ 987 function date_calc_prev_day_of_week($dow, $day = 0, $month = 0, $year = 0, 988 $format = DATE_CALC_FORMAT, $on_or_before = false) { 989 if (empty($year)) { 990 $year = date_calc_get_year(); 991 } 992 if (empty($month)) { 993 $month = date_calc_get_month(); 994 } 995 if (empty($day)) { 996 $day = date_calc_get_day(); 997 } 998 $days = date_calc_date_to_days($day, $month, $year); 999 $curr_weekday = date_dow($day, $month, $year); 1000 if ($curr_weekday == $dow) { 1001 if (!$on_or_before) { 1002 $days -= 7; 1003 } 1004 } 1005 elseif ($curr_weekday < $dow) { 1006 $days -= 7 - ($dow - $curr_weekday); 1007 } 1008 else { 1009 $days -= $curr_weekday - $dow; 1010 } 1011 return date_calc_days_to_date($days, $format); 1012 } 1013 1014 /** 1015 * Returns date of the next specific day of the week 1016 * from the given date. 1017 * 1018 * @param int $dow 1019 * The day of the week (0 = Sunday). 1020 * @param int $day 1021 * The day of the month. 1022 * @param int $month 1023 * The month. 1024 * @param int $year 1025 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1026 * @param bool $on_or_after 1027 * If true and days are same, returns current day. 1028 * @param string $format 1029 * The string indicating how to format the output. 1030 * 1031 * @return string the date in the desired format 1032 */ 1033 function date_calc_next_day_of_week($dow, $day = 0, $month = 0, $year = 0, 1034 $format = DATE_CALC_FORMAT, $on_or_after = false) { 1035 if (empty($year)) { 1036 $year = date_calc_get_year(); 1037 } 1038 if (empty($month)) { 1039 $month = date_calc_get_month(); 1040 } 1041 if (empty($day)) { 1042 $day = date_calc_get_day(); 1043 } 1044 $days = date_calc_date_to_days($day, $month, $year); 1045 $curr_weekday = date_dow($day, $month, $year); 1046 if ($curr_weekday == $dow) { 1047 if (!$on_or_after) { 1048 $days += 7; 1049 } 1050 } 1051 elseif ($curr_weekday > $dow) { 1052 $days += 7 - ($curr_weekday - $dow); 1053 } 1054 else { 1055 $days += $dow - $curr_weekday; 1056 } 1057 return date_calc_days_to_date($days, $format); 1058 } 1059 1060 /** 1061 * Find the month day of the beginning of week for given date, 1062 * using variable_get('date_first_day', 1). Can return weekday of prev month. 1063 * 1064 * @param int $day 1065 * The day of the month. 1066 * @param int $month 1067 * The month. 1068 * @param int $year 1069 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1070 * @param string $format 1071 * The string indicating how to format the output. 1072 * 1073 * @return string 1074 * The date in the desired format. 1075 */ 1076 function date_calc_begin_of_week($day = 0, $month = 0, $year = 0, 1077 $format = DATE_CALC_FORMAT) { 1078 if (empty($year)) { 1079 $year = date_calc_get_year(); 1080 } 1081 if (empty($month)) { 1082 $month = date_calc_get_month(); 1083 } 1084 if (empty($day)) { 1085 $day = date_calc_get_day(); 1086 } 1087 $this_weekday = date_dow($day, $month, $year); 1088 $interval = (7 - variable_get('date_first_day', 1) + $this_weekday) % 7; 1089 return date_calc_days_to_date(date_calc_date_to_days($day, $month, $year) 1090 - $interval, $format); 1091 } 1092 1093 /** 1094 * Find the month day of the end of week for given date, using 1095 * variable_get('date_first_day', 1). Can return weekday of following month. 1096 * 1097 * @param int $day 1098 * The day of the month. 1099 * @param int $month 1100 * The month. 1101 * @param int $year 1102 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1103 * @param string $format 1104 * The string indicating how to format the output. 1105 * 1106 * @return string 1107 * The date in the desired format. 1108 */ 1109 function date_calc_end_of_week($day = 0, $month = 0, $year = 0, 1110 $format = DATE_CALC_FORMAT) { 1111 if (empty($year)) { 1112 $year = date_calc_get_year(); 1113 } 1114 if (empty($month)) { 1115 $month = date_calc_get_month(); 1116 } 1117 if (empty($day)) { 1118 $day = date_calc_get_day(); 1119 } 1120 $this_weekday = date_dow($day, $month, $year); 1121 $interval = (6 + variable_get('date_first_day', 1) - $this_weekday) % 7; 1122 return date_calc_days_to_date(date_calc_date_to_days($day, $month, $year) 1123 + $interval, $format); 1124 } 1125 1126 /** 1127 * Find the month day of the beginning of week before given date, using 1128 * variable_get('date_first_day', 1). Can return weekday of prev month. 1129 * 1130 * @param int $day 1131 * The day of the month. 1132 * @param int $month 1133 * The month. 1134 * @param int $year 1135 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1136 * @param string $format 1137 * The string indicating how to format the output. 1138 * 1139 * @return string 1140 * The date in the desired format. 1141 */ 1142 function date_calc_begin_of_prev_week($day = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 1143 if (empty($year)) { 1144 $year = date_calc_get_year(); 1145 } 1146 if (empty($month)) { 1147 $month = date_calc_get_month(); 1148 } 1149 if (empty($day)) { 1150 $day = date_calc_get_day(); 1151 } 1152 $date = date_calc_days_to_date(date_calc_date_to_days($day-7, $month, $year), '%Y%m%d'); 1153 $prev_week_year = intval(substr($date, 0, 4)); 1154 $prev_week_month = intval(substr($date, 4, 2)); 1155 $prev_week_day = intval(substr($date, 6, 2)); 1156 return date_calc_begin_of_week($prev_week_day, $prev_week_month, $prev_week_year, $format); 1157 } 1158 1159 /** 1160 * Find the month day of the beginning of week after given date, using 1161 * variable_get('date_first_day', 1). Can return weekday of next month. 1162 * 1163 * @param int $day 1164 * The day of the month. 1165 * @param int $month 1166 * The month. 1167 * @param int $year 1168 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1169 * @param string $format 1170 * The string indicating how to format the output. 1171 * 1172 * @return string the date in the desired format 1173 */ 1174 function date_calc_begin_of_next_week($day = 0, $month = 0, $year = 0, 1175 $format = DATE_CALC_FORMAT) { 1176 if (empty($year)) { 1177 $year = date_calc_get_year(); 1178 } 1179 if (empty($month)) { 1180 $month = date_calc_get_month(); 1181 } 1182 if (empty($day)) { 1183 $day = date_calc_get_day(); 1184 } 1185 $date = date_calc_days_to_date(date_calc_date_to_days($day + 7, $month, $year), '%Y%m%d'); 1186 $next_week_year = intval(substr($date, 0, 4)); 1187 $next_week_month = intval(substr($date, 4, 2)); 1188 $next_week_day = intval(substr($date, 6, 2)); 1189 return date_calc_begin_of_week($next_week_day, $next_week_month, $next_week_year, $format); 1190 } 1191 1192 /** 1193 * Returns date of the first day of the month in the number of months 1194 * from the given date 1195 * 1196 * @param int $months 1197 * The number of months from the date provided. 1198 * Positive numbers go into the future. 1199 * Negative numbers go into the past. 1200 * 0 is the month presented in $month. 1201 * @param int $month 1202 * The month. 1203 * @param int $year 1204 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1205 * @param string $format 1206 * The string indicating how to format the output. 1207 * 1208 * @return string 1209 * The date in the desired format. 1210 */ 1211 function date_calc_begin_of_month_by_span($months = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 1212 if (empty($year)) { 1213 $year = date_calc_get_year(); 1214 } 1215 if (empty($month)) { 1216 $month = date_calc_get_month(); 1217 } 1218 if ($months > 0) { 1219 // future month 1220 $tmp_mo = $month + $months; 1221 $month = $tmp_mo % 12; 1222 if ($month == 0) { 1223 $month = 12; 1224 $year = $year + floor(($tmp_mo - 1) / 12); 1225 } 1226 else { 1227 $year = $year + floor($tmp_mo / 12); 1228 } 1229 } 1230 else { 1231 // past or present month 1232 $tmp_mo = $month + $months; 1233 if ($tmp_mo > 0) { 1234 // same year 1235 $month = $tmp_mo; 1236 } 1237 elseif ($tmp_mo == 0) { 1238 // prior dec 1239 $month = 12; 1240 $year--; 1241 } 1242 else { 1243 // some time in a prior year 1244 $month = 12 + ($tmp_mo % 12); 1245 $year = $year + floor($tmp_mo / 12); 1246 } 1247 } 1248 return date_calc_format(1, $month, $year, $format); 1249 } 1250 1251 /** 1252 * Returns date of the last day of the month in the number of months 1253 * from the given date. 1254 * 1255 * @param int $months 1256 * The number of months from the date provided. 1257 * Positive numbers go into the future. 1258 * Negative numbers go into the past. 1259 * 0 is the month presented in $month. 1260 * @param int $month 1261 * The month. 1262 * @param int $year 1263 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1264 * @param string $format 1265 * The string indicating how to format the output. 1266 * 1267 * @return string 1268 * The date in the desired format. 1269 */ 1270 function date_calc_end_of_month_by_span($months = 0, $month = 0, $year = 0, $format = DATE_CALC_FORMAT) { 1271 if (empty($year)) { 1272 $year = date_calc_get_year(); 1273 } 1274 if (empty($month)) { 1275 $month = date_calc_get_month(); 1276 } 1277 if ($months > 0) { 1278 // future month 1279 $tmp_mo = $month + $months; 1280 $month = $tmp_mo % 12; 1281 if ($month == 0) { 1282 $month = 12; 1283 $year = $year + floor(($tmp_mo - 1) / 12); 1284 } 1285 else { 1286 $year = $year + floor($tmp_mo / 12); 1287 } 1288 } 1289 else { 1290 // past or present month 1291 $tmp_mo = $month + $months; 1292 if ($tmp_mo > 0) { 1293 // same year 1294 $month = $tmp_mo; 1295 } 1296 elseif ($tmp_mo == 0) { 1297 // prior dec 1298 $month = 12; 1299 $year--; 1300 } 1301 else { 1302 // some time in a prior year 1303 $month = 12 + ($tmp_mo % 12); 1304 $year = $year + floor($tmp_mo / 12); 1305 } 1306 } 1307 return date_calc_format(date_calc_days_in_month($month, $year), $month, $year, $format); 1308 } 1309 1310 /** 1311 * Find the day of the week for the first of the month of given date 1312 * 1313 * @param int $month 1314 * The month. 1315 * @param int $year 1316 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1317 * 1318 * @return int 1319 * Number of weekday for the first day, 0=Sunday. 1320 */ 1321 function date_calc_first_of_month_weekday($month = 0, $year = 0) { 1322 if (empty($year)) { 1323 $year = date_calc_get_year(); 1324 } 1325 if (empty($month)) { 1326 $month = date_calc_get_month(); 1327 } 1328 return date_dow('01', $month, $year); 1329 } 1330 1331 /** 1332 * Calculates the date of the Nth weekday of the month, 1333 * such as the second Saturday of January 2000 1334 * 1335 * @param int $week 1336 * The number of the week to get (1 = first, etc. Also can be 'last'.) 1337 * @param int $dow 1338 * The day of the week (0 = Sunday). 1339 * @param int $month 1340 * The month. 1341 * @param int $year 1342 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1343 * @param string $format 1344 * The string indicating how to format the output. 1345 * 1346 * @return string 1347 * The date in the desired format. 1348 */ 1349 function date_calc_n_weekday_of_month($week, $dow, $month, $year, $format = DATE_CALC_FORMAT) { 1350 if (is_numeric($week)) { 1351 $DOW1day = ($week - 1) * 7 + 1; 1352 $DOW1 = date_dow($DOW1day, $month, $year); 1353 $wdate = ($week - 1) * 7 + 1 + (7 + $dow - $DOW1) % 7; 1354 if ($wdate > date_calc_days_in_month($month, $year)) { 1355 return -1; 1356 } 1357 else { 1358 return date_calc_format($wdate, $month, $year, $format); 1359 } 1360 } 1361 elseif ($week == 'last' && $dow < 7) { 1362 $lastday = date_calc_days_in_month($month, $year); 1363 $lastdow = date_dow($lastday, $month, $year); 1364 $diff = $dow - $lastdow; 1365 if ($diff > 0) { 1366 return date_calc_format($lastday - (7 - $diff), $month, $year, $format); 1367 } 1368 else { 1369 return date_calc_format($lastday + $diff, $month, $year, $format); 1370 } 1371 } 1372 else { 1373 return -1; 1374 } 1375 } 1376 1377 /** 1378 * Determines if given date is a future date from now 1379 * 1380 * @param int $day 1381 * The day of the month. 1382 * @param int $month 1383 * The month. 1384 * @param int $year 1385 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1386 * 1387 * @return boolean 1388 */ 1389 function date_calc_is_future_date($day, $month, $year) { 1390 $this_year = date_calc_get_year(); 1391 $this_month = date_calc_get_month(); 1392 $this_day = date_calc_get_day(); 1393 if ($year > $this_year) { 1394 return true; 1395 } 1396 elseif ($year == $this_year) { 1397 if ($month > $this_month) { 1398 return true; 1399 } 1400 elseif ($month == $this_month) { 1401 if ($day > $this_day) { 1402 return true; 1403 } 1404 } 1405 } 1406 return false; 1407 } 1408 1409 /** 1410 * Determines if given date is a past date from now 1411 * 1412 * @param int $day 1413 * the day of the month 1414 * @param int $month 1415 * the month 1416 * @param int $year 1417 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1418 * 1419 * @return boolean 1420 */ 1421 function date_calc_is_past_date($day, $month, $year) { 1422 $this_year = date_calc_get_year(); 1423 $this_month = date_calc_get_month(); 1424 $this_day = date_calc_get_day(); 1425 if ($year < $this_year) { 1426 return true; 1427 } 1428 elseif ($year == $this_year) { 1429 if ($month < $this_month) { 1430 return true; 1431 } 1432 elseif ($month == $this_month) { 1433 if ($day < $this_day) { 1434 return true; 1435 } 1436 } 1437 } 1438 return false; 1439 } 1440 1441 /** 1442 * Returns number of days between two given dates 1443 * 1444 * @param int $day1 1445 * the day of the month 1446 * @param int $month1 1447 * the month 1448 * @param int $year1 1449 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1450 * @param int $day2 1451 * the day of the month 1452 * @param int $month2 1453 * the month 1454 * @param int $year2 1455 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1456 * 1457 * @return int 1458 * the absolute number of days between the two dates. 1459 * If an error occurs, -1 is returned. 1460 */ 1461 function date_calc_date_diff($day1, $month1, $year1, $day2, $month2, $year2) { 1462 if (!date_calc_is_valid($day1, $month1, $year1)) { 1463 return -1; 1464 } 1465 if (!date_calc_is_valid($day2, $month2, $year2)) { 1466 return -1; 1467 } 1468 return abs(date_calc_date_to_days($day1, $month1, $year1) 1469 - date_calc_date_to_days($day2, $month2, $year2)); 1470 } 1471 1472 /** 1473 * Compares two dates 1474 * 1475 * @param int $day1 1476 * the day of the month 1477 * @param int $month1 1478 * the month 1479 * @param int $year1 1480 * The 4 digit year. Do not add leading 0's for years prior to 1000. 1481 * @param int $day2 1482 * the day of the month 1483 * @param int $month2 1484 * the month 1485 * @param int $year2 1486 * the year. Use the complete year instead of the abbreviated version. 1487 * E.g. use 2005, not 05. Do not add leading 0's for years prior to 1000. 1488 * 1489 * @return int 1490 * 0 if the dates are equal. 1 if date 1 is later, -1 if date 1 is earlier. 1491 */ 1492 function date_calc_compare_dates($day1, $month1, $year1, $day2, $month2, $year2) { 1493 $ndays1 = date_calc_date_to_days($day1, $month1, $year1); 1494 $ndays2 = date_calc_date_to_days($day2, $month2, $year2); 1495 if ($ndays1 == $ndays2) { 1496 return 0; 1497 } 1498 return ($ndays1 > $ndays2) ? 1 : -1; 1499 }
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 |