1<?php 2/* vim: set expandtab tabstop=4 shiftwidth=4: */ 3/** 4 * Driver for holidays in Japanese 5 * 6 * PHP Version 5 7 * 8 * Copyright (c) 1997-2008 The PHP Group 9 * 10 * This source file is subject to version 3.0 of the PHP license, 11 * that is bundled with this package in the file LICENSE, and is 12 * available at through the world-wide-web at 13 * http://www.php.net/license/3_01.txt. 14 * If you did not receive a copy of the PHP license and are unable to 15 * obtain it through the world-wide-web, please send a note to 16 * license@php.net so we can mail you a copy immediately. 17 * 18 * @category Date 19 * @package Date_Holidays 20 * @author Hideyuki Shimooka <shimooka@doyouphp.jp> 21 * @license http://www.php.net/license/3_01.txt PHP License 3.0.1 22 * @version CVS: $Id$ 23 * @link http://pear.php.net/package/Date_Holidays 24 * @see http://www.h3.dion.ne.jp/~sakatsu/holiday_topic.htm 25 */ 26 27/** 28 * Extends Date_Holidays_Driver 29 */ 30require_once 'Date/Holidays/Driver.php'; 31 32/** 33 * the gradient parameter of the approximate expression 34 * to calculate equinox day 35 * 36 * @access public 37 */ 38define('DATE_HOLIDAYS_EQUINOX_GRADIENT', 0.242194); 39 40/** 41 * the initial parameter of the approximate expression 42 * to calculate vernal equinox day from 1948 to 1979 43 * 44 * @access public 45 */ 46define('DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_1979', 20.8357); 47 48/** 49 * the initial parameter of the approximate expression 50 * to calculate vernal equinox day from 1980 to 2099 51 * 52 * @access public 53 */ 54define('DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_2099', 20.8431); 55 56/** 57 * the initial parameter of the approximate expression 58 * to calculate vernal equinox day from 2100 to 2150 59 * 60 * @access public 61 */ 62define('DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_2150', 21.8510); 63 64/** 65 * the initial parameter of the approximate expression 66 * to calculate autumnal equinox day from 1948 to 1979 67 * 68 * @access public 69 */ 70define('DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_1979', 23.2588); 71 72/** 73 * the initial parameter of the approximate expression 74 * to calculate autumnal equinox day from 1980 to 2099 75 * 76 * @access public 77 */ 78define('DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_2099', 23.2488); 79 80/** 81 * the initial parameter of the approximate expression 82 * to calculate autumnal equinox day from 2100 to 2150 83 * 84 * @access public 85 */ 86define('DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_2150', 24.2488); 87 88/** 89 * class that calculates Japanese holidays 90 * 91 * @category Date 92 * @package Date_Holidays 93 * @subpackage Driver 94 * @author Hideyuki Shimooka <shimooka@doyouphp.jp> 95 * @license http://www.php.net/license/3_01.txt PHP License 3.0.1 96 * @version CVS: $Id$ 97 * @link http://pear.php.net/package/Date_Holidays 98 * @see http://www.h3.dion.ne.jp/~sakatsu/holiday_topic.htm 99 */ 100class Date_Holidays_Driver_Japan extends Date_Holidays_Driver 101{ 102 /** 103 * this driver's name 104 * 105 * @access protected 106 * @var string 107 */ 108 var $_driverName = 'Japan'; 109 110 /** 111 * a translation file name 112 * 113 * @access private 114 */ 115 var $_translationFile = null; 116 117 /** 118 * a translation locale 119 * 120 * @access private 121 */ 122 var $_translationLocale = null; 123 124 /** 125 * Constructor 126 * 127 * Use the Date_Holidays::factory() method to construct an object of a 128 * certain driver 129 * 130 * @access protected 131 */ 132 public function __construct() 133 { 134 } 135 136 /** 137 * Build the internal arrays that contain data about the calculated holidays 138 * 139 * @access protected 140 * @return boolean true on success, otherwise a PEAR_ErrorStack object 141 * @throws object PEAR_ErrorStack 142 */ 143 function _buildHolidays() 144 { 145 parent::_buildHolidays(); 146 147 $this->_clearHolidays(); 148 149 $this->_buildNewYearsDay(); 150 $this->_buildComingofAgeDay(); 151 $this->_buildNationalFoundationDay(); 152 $this->_buildVernalEquinoxDay(); 153 $this->_buildShowaDay(); 154 $this->_buildConstitutionMemorialDay(); 155 $this->_buildGreeneryDay(); 156 $this->_buildChildrensDay(); 157 $this->_buildMarineDay(); 158 $this->_buildMountainDay(); 159 $this->_buildRespectfortheAgedDay(); 160 $this->_buildAutumnalEquinoxDay(); 161 $this->_buildHealthandSportsDay(); 162 $this->_buildNationalCultureDay(); 163 $this->_buildLaborThanksgivingDay(); 164 $this->_buildEmperorsBirthday(); 165 166 $this->_buildOtherMemorialDays(); 167 168 $this->_buildSubstituteHolidays(); 169 170 return true; 171 } 172 173 /** 174 * Method that returns an array containing the ISO3166 codes that may possibly 175 * identify a driver. 176 * 177 * @static 178 * @access public 179 * @return array possible ISO3166 codes 180 */ 181 function getISO3166Codes() 182 { 183 return array('jp', 'jpn'); 184 } 185 186 /** 187 * build day of New Year's Day 188 * 189 * @access private 190 * @return void 191 */ 192 function _buildNewYearsDay() 193 { 194 if ($this->_year >= 1949) { 195 $this->_addHoliday('newYearsDay', 196 $this->_year . '-01-01', 197 'New Year\'s Day'); 198 } 199 } 200 201 /** 202 * build day of Coming of Age Day 203 * 204 * @access private 205 * @return void 206 */ 207 function _buildComingofAgeDay() 208 { 209 $date = null; 210 if ($this->_year >= 2000) { 211 $date = $this->_calcNthMondayInMonth(1, 2); 212 } else if ($this->_year >= 1949) { 213 $date = $this->_year . '-01-15'; 214 } 215 if (!is_null($date)) { 216 $this->_addHoliday('comingOfAgeDay', 217 $date, 218 'Coming of Age Day'); 219 } 220 } 221 222 /** 223 * build day of National Foundation Day 224 * 225 * @access private 226 * @return void 227 */ 228 function _buildNationalFoundationDay() 229 { 230 if ($this->_year >= 1949) { 231 $this->_addHoliday('nationalFoundationDay', 232 $this->_year . '-02-11', 233 'National Foundation Day'); 234 } 235 } 236 237 /** 238 * build day of Vernal Equinox Day 239 * 240 * use approximate expression to calculate equinox day internally. 241 * 242 * @access private 243 * @return void 244 * @see http://www.h3.dion.ne.jp/~sakatsu/holiday_topic.htm (in Japanese) 245 */ 246 function _buildVernalEquinoxDay() 247 { 248 $day = null; 249 if ($this->_year >= 1948 && $this->_year <= 1979) { 250 $day = floor(DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_1979 + 251 DATE_HOLIDAYS_EQUINOX_GRADIENT * 252 ($this->_year - 1980) - 253 floor(($this->_year - 1980) / 4)); 254 } else if ($this->_year <= 2099) { 255 $day = floor(DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_2099 + 256 DATE_HOLIDAYS_EQUINOX_GRADIENT * 257 ($this->_year - 1980) - 258 floor(($this->_year - 1980) / 4)); 259 } else if ($this->_year <= 2150) { 260 $day = floor(DATE_HOLIDAYS_VERNAL_EQUINOX_PARAM_2150 + 261 DATE_HOLIDAYS_EQUINOX_GRADIENT * 262 ($this->_year - 1980) - 263 floor(($this->_year - 1980) / 4)); 264 } 265 if (!is_null($day)) { 266 $this->_addHoliday('vernalEquinoxDay', 267 sprintf('%04d-%02d-%02d', $this->_year, 3, $day), 268 'Vernal Equinox Day'); 269 } 270 } 271 272 /** 273 * build day of Showa Day 274 * 275 * @access private 276 * @return void 277 */ 278 function _buildShowaDay() 279 { 280 $internalName = null; 281 $title = null; 282 if ($this->_year >= 2007) { 283 $internalName = 'showaDay'; 284 $title = 'Showa Day'; 285 } else if ($this->_year >= 1989) { 286 $internalName = 'greeneryDay'; 287 $title = 'Greenery Day'; 288 } else if ($this->_year >= 1949) { 289 $internalName = 'showaEmperorsBirthday'; 290 $title = 'Showa Emperor\'s Birthday'; 291 } 292 if (!is_null($internalName)) { 293 $this->_addHoliday($internalName, 294 $this->_year . '-04-29', 295 $title); 296 } 297 } 298 299 /** 300 * build day of Constitution Memorial Day 301 * 302 * @access private 303 * @return void 304 */ 305 function _buildConstitutionMemorialDay() 306 { 307 if ($this->_year >= 1949) { 308 $this->_addHoliday('constitutionMemorialDay', 309 $this->_year . '-05-03', 310 'Constitution Memorial Day'); 311 } 312 } 313 314 /** 315 * build day of Greenery Day 316 * 317 * @access private 318 * @return void 319 */ 320 function _buildGreeneryDay() 321 { 322 $internalName = null; 323 $title = null; 324 if ($this->_year >= 2007) { 325 $internalName = 'greeneryDay'; 326 $title = 'Greenery Day'; 327 } else if ($this->_year >= 1986) { 328 $date =& new Date($this->_year . '-05-04'); 329 if ($date->getDayOfWeek() != 0) { 330 $internalName = 'nationalHoliday'; 331 $title = 'National Holiday'; 332 } 333 } 334 if (!is_null($internalName)) { 335 $this->_addHoliday($internalName, 336 $this->_year . '-05-04', 337 $title); 338 } 339 } 340 341 /** 342 * build day of Children's Day 343 * 344 * @access private 345 * @return void 346 */ 347 function _buildChildrensDay() 348 { 349 if ($this->_year >= 1949) { 350 $this->_addHoliday('childrensDay', 351 $this->_year . '-05-05', 352 'Children\'s Day'); 353 } 354 } 355 356 /** 357 * build day of Marine Day 358 * 359 * @access private 360 * @return void 361 */ 362 function _buildMarineDay() 363 { 364 $date = null; 365 if ($this->_year >= 2003) { 366 $date = $this->_calcNthMondayInMonth(7, 3); 367 } else if ($this->_year >= 1996) { 368 $date = $this->_year . '-07-20'; 369 } 370 if (!is_null($date)) { 371 $this->_addHoliday('marineDay', 372 $date, 373 'Marine Day'); 374 } 375 } 376 377 /** 378 * build day of Mountain Day 379 * 380 * @access private 381 * @return void 382 */ 383 function _buildMountainDay() 384 { 385 $date = null; 386 if ($this->_year >= 2016) { 387 $date = $this->_year . '-08-11'; 388 } 389 if (!is_null($date)) { 390 $this->_addHoliday('mountainDay', 391 $date, 392 'Mountain Day'); 393 } 394 } 395 396 /** 397 * build day of Respect for the Aged Day 398 * 399 * @access private 400 * @return void 401 */ 402 function _buildRespectfortheAgedDay() 403 { 404 $date = null; 405 if ($this->_year >= 2003) { 406 $date = $this->_calcNthMondayInMonth(9, 3); 407 } else if ($this->_year >= 1966) { 408 $date = $this->_year . '-09-15'; 409 } 410 if (!is_null($date)) { 411 $this->_addHoliday('respectfortheAgedDay', 412 $date, 413 'Respect for the Aged Day'); 414 } 415 } 416 417 /** 418 * build day of Health and Sports Day 419 * 420 * @access private 421 * @return void 422 */ 423 function _buildHealthandSportsDay() 424 { 425 $date = null; 426 if ($this->_year >= 2000) { 427 $date = $this->_calcNthMondayInMonth(10, 2); 428 } else if ($this->_year >= 1966) { 429 $date = $this->_year . '-10-10'; 430 } 431 if (!is_null($date)) { 432 $this->_addHoliday('healthandSportsDay', 433 $date, 434 'Health and Sports Day'); 435 } 436 } 437 438 /** 439 * build day of Autumnal Equinox Day 440 * 441 * use approximate expression to calculate equinox day internally. 442 * 443 * @access private 444 * @return void 445 * @see http://www.h3.dion.ne.jp/~sakatsu/holiday_topic.htm (in Japanese) 446 */ 447 function _buildAutumnalEquinoxDay() 448 { 449 $day = null; 450 if ($this->_year >= 1948 && $this->_year <= 1979) { 451 $day = floor(DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_1979 + 452 DATE_HOLIDAYS_EQUINOX_GRADIENT * 453 ($this->_year - 1980) - 454 floor(($this->_year - 1980) / 4)); 455 } else if ($this->_year <= 2099) { 456 $day = floor(DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_2099 + 457 DATE_HOLIDAYS_EQUINOX_GRADIENT * 458 ($this->_year - 1980) - 459 floor(($this->_year - 1980) / 4)); 460 } else if ($this->_year <= 2150) { 461 $day = floor(DATE_HOLIDAYS_AUTUMNAL_EQUINOX_PARAM_2150 + 462 DATE_HOLIDAYS_EQUINOX_GRADIENT * 463 ($this->_year - 1980) - 464 floor(($this->_year - 1980) / 4)); 465 } 466 if (!is_null($day)) { 467 $this->_addHoliday('autumnalEquinoxDay', 468 sprintf('%04d-%02d-%02d', $this->_year, 9, $day), 469 'Autumnal Equinox Day'); 470 471 if ($this->_year >= 2003 && 472 $this->getHolidayDate('autumnalEquinoxDay')->getDayOfWeek() == 3) { 473 $this->_addHoliday('nationalHolidayBeforeAutumnalEquinoxDay', 474 $this->getHolidayDate('autumnalEquinoxDay')->getPrevDay(), 475 'National Holiday before Autumnal Equinox Day'); 476 } 477 } 478 } 479 480 /** 481 * build day of National Culture Day 482 * 483 * @access private 484 * @return void 485 */ 486 function _buildNationalCultureDay() 487 { 488 if ($this->_year >= 1948) { 489 $this->_addHoliday('nationalCultureDay', 490 $this->_year . '-11-03', 491 'National Culture Day'); 492 } 493 } 494 495 /** 496 * build day of Labor Thanksgiving Day 497 * 498 * @access private 499 * @return void 500 */ 501 function _buildLaborThanksgivingDay() 502 { 503 if ($this->_year >= 1948) { 504 $this->_addHoliday('laborThanksgivingDay', 505 $this->_year . '-11-23', 506 'Labor Thanksgiving Day'); 507 } 508 } 509 510 /** 511 * build day of Emperor's Birthday 512 * 513 * @access private 514 * @return void 515 */ 516 function _buildEmperorsBirthday() 517 { 518 if ($this->_year >= 1989) { 519 $this->_addHoliday('emperorsBirthday', 520 $this->_year . '-12-23', 521 'Emperor\'s Birthday'); 522 } 523 } 524 525 /** 526 * build day of Emperor's Birthday 527 * 528 * @access private 529 * @return void 530 */ 531 function _buildOtherMemorialDays() 532 { 533 if ($this->_year == 1959) { 534 $this->_addHoliday('theRiteofWeddingofHIHCrownPrinceAkihito', 535 $this->_year . '-04-10', 536 'The Rite of Wedding of HIH Crown Prince Akihito'); 537 } 538 if ($this->_year == 1989) { 539 $this->_addHoliday('theFuneralCeremonyofEmperorShowa.', 540 $this->_year . '-02-24', 541 'The Funeral Ceremony of Emperor Showa.'); 542 } 543 if ($this->_year == 1990) { 544 $this->_addHoliday('theCeremonyoftheEnthronementof' 545 . 'HisMajestytheEmperor(attheSeiden)', 546 $this->_year . '-11-12', 547 'The Ceremony of the Enthronement of ' . 548 'His Majesty the Emperor (at the Seiden)'); 549 } 550 if ($this->_year == 1993) { 551 $this->_addHoliday('theRiteofWeddingofHIHCrownPrinceNaruhito', 552 $this->_year . '-06-09', 553 'The Rite of Wedding of HIH Crown Prince Naruhito'); 554 } 555 } 556 557 /** 558 * build day of substitute holiday 559 * 560 * @access private 561 * @return void 562 */ 563 function _buildSubstituteHolidays() 564 { 565 // calculate 'current' substitute holidays 566 foreach ($this->_dates as $internalName => $date) { 567 if ($date->getDayOfWeek() == 0) { 568 if ($this->_year >= 2007) { 569 while (in_array($date, $this->_dates)) { 570 $date = $date->getNextDay(); 571 } 572 } else if ($date->getDate() >= '1973-04-12') { 573 $date = $date->getNextDay(); 574 if (in_array($date, $this->_dates)) { 575 continue; 576 } 577 } else { 578 continue; 579 } 580 if (!is_null($date)) { 581 $name = 'substituteHolidayFor' . $internalName; 582 $this->_addHoliday($name, 583 $date, 584 'Substitute Holiday for ' . 585 $this->_titles['C'][$internalName]); 586 } 587 } 588 } 589 590 // reset translated titles if set. 591 // because substitute Holidays change each year. 592 if (!is_null($this->_translationFile)) { 593 $ext = substr($this->_translationFile, -3); 594 if ($ext === 'xml') { 595 $this->addTranslationFile($this->_translationFile, 596 $this->_translationLocale); 597 } else if ($ext === 'ser') { 598 $this->addCompiledTranslationFile($this->_translationFile, 599 $this->_translationLocale); 600 } 601 } 602 } 603 604 605 /** 606 * Add a language-file's content 607 * 608 * The language-file's content will be parsed and translations, 609 * properties, etc. for holidays will be made available with the specified 610 * locale. 611 * 612 * @param string $file filename of the language file 613 * @param string $locale locale-code of the translation 614 * 615 * @access public 616 * @return boolean true on success, otherwise a PEAR_ErrorStack object 617 * @throws object PEAR_Errorstack 618 */ 619 function addTranslationFile($file, $locale) 620 { 621 $result = parent::addTranslationFile($file, $locale); 622 if (PEAR::isError($result)) { 623 return $result; 624 } 625 $this->_translationFile = $file; 626 $this->_translationLocale = $locale; 627 return $result; 628 } 629 630 /** 631 * Add a compiled language-file's content 632 * 633 * The language-file's content will be unserialized and translations, 634 * properties, etc. for holidays will be made available with the 635 * specified locale. 636 * 637 * @param string $file filename of the compiled language file 638 * @param string $locale locale-code of the translation 639 * 640 * @access public 641 * @return boolean true on success, otherwise a PEAR_ErrorStack object 642 * @throws object PEAR_Errorstack 643 */ 644 function addCompiledTranslationFile($file, $locale) 645 { 646 $result = parent::addCompiledTranslationFile($file, $locale); 647 if (PEAR::isError($result)) { 648 return $result; 649 } 650 $this->_translationFile = $file; 651 $this->_translationLocale = $locale; 652 return $result; 653 } 654 655 /** 656 * clear all holidays 657 * 658 * @access private 659 * @return void 660 */ 661 function _clearHolidays() 662 { 663 $this->_holidays = array(); 664 $this->_internalNames = array(); 665 $this->_dates = array(); 666 $this->_titles = array(); 667 } 668} 669?> 670