php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #67425
Patch Language.php.diff revision 2014-06-12 15:06 UTC by federicoleva at tiscali dot it

Patch Language.php.diff for Date/time related Bug #67425

Patch version 2014-06-12 15:06 UTC

Return to Bug #67425 | Download this patch
Patch Revisions:

Developer: federicoleva@tiscali.it

0a1,7
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getMonthName( $key ) {
> 		return $this->getMessageFromDB( self::$mMonthMsgs[$key - 1] );
> 	}
1a9,846
> 	/**
> 	 * @return array
> 	 */
> 	function getMonthNamesArray() {
> 		$monthNames = array( '' );
> 		for ( $i = 1; $i < 13; $i++ ) {
> 			$monthNames[] = $this->getMonthName( $i );
> 		}
> 		return $monthNames;
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getMonthNameGen( $key ) {
> 		return $this->getMessageFromDB( self::$mMonthGenMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getMonthAbbreviation( $key ) {
> 		return $this->getMessageFromDB( self::$mMonthAbbrevMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @return array
> 	 */
> 	function getMonthAbbreviationsArray() {
> 		$monthNames = array( '' );
> 		for ( $i = 1; $i < 13; $i++ ) {
> 			$monthNames[] = $this->getMonthAbbreviation( $i );
> 		}
> 		return $monthNames;
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getWeekdayName( $key ) {
> 		return $this->getMessageFromDB( self::$mWeekdayMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getWeekdayAbbreviation( $key ) {
> 		return $this->getMessageFromDB( self::$mWeekdayAbbrevMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getIranianCalendarMonthName( $key ) {
> 		return $this->getMessageFromDB( self::$mIranianCalendarMonthMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getHebrewCalendarMonthName( $key ) {
> 		return $this->getMessageFromDB( self::$mHebrewCalendarMonthMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getHebrewCalendarMonthNameGen( $key ) {
> 		return $this->getMessageFromDB( self::$mHebrewCalendarMonthGenMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * @param string $key
> 	 * @return string
> 	 */
> 	function getHijriCalendarMonthName( $key ) {
> 		return $this->getMessageFromDB( self::$mHijriCalendarMonthMsgs[$key - 1] );
> 	}
> 
> 	/**
> 	 * This is a workalike of PHP's date() function, but with better
> 	 * internationalisation, a reduced set of format characters, and a better
> 	 * escaping format.
> 	 *
> 	 * Supported format characters are dDjlNwzWFmMntLoYyaAgGhHiscrUeIOPTZ. See
> 	 * the PHP manual for definitions. There are a number of extensions, which
> 	 * start with "x":
> 	 *
> 	 *    xn   Do not translate digits of the next numeric format character
> 	 *    xN   Toggle raw digit (xn) flag, stays set until explicitly unset
> 	 *    xr   Use roman numerals for the next numeric format character
> 	 *    xh   Use hebrew numerals for the next numeric format character
> 	 *    xx   Literal x
> 	 *    xg   Genitive month name
> 	 *
> 	 *    xij  j (day number) in Iranian calendar
> 	 *    xiF  F (month name) in Iranian calendar
> 	 *    xin  n (month number) in Iranian calendar
> 	 *    xiy  y (two digit year) in Iranian calendar
> 	 *    xiY  Y (full year) in Iranian calendar
> 	 *
> 	 *    xjj  j (day number) in Hebrew calendar
> 	 *    xjF  F (month name) in Hebrew calendar
> 	 *    xjt  t (days in month) in Hebrew calendar
> 	 *    xjx  xg (genitive month name) in Hebrew calendar
> 	 *    xjn  n (month number) in Hebrew calendar
> 	 *    xjY  Y (full year) in Hebrew calendar
> 	 *
> 	 *    xmj  j (day number) in Hijri calendar
> 	 *    xmF  F (month name) in Hijri calendar
> 	 *    xmn  n (month number) in Hijri calendar
> 	 *    xmY  Y (full year) in Hijri calendar
> 	 *
> 	 *    xkY  Y (full year) in Thai solar calendar. Months and days are
> 	 *                       identical to the Gregorian calendar
> 	 *    xoY  Y (full year) in Minguo calendar or Juche year.
> 	 *                       Months and days are identical to the
> 	 *                       Gregorian calendar
> 	 *    xtY  Y (full year) in Japanese nengo. Months and days are
> 	 *                       identical to the Gregorian calendar
> 	 *
> 	 * Characters enclosed in double quotes will be considered literal (with
> 	 * the quotes themselves removed). Unmatched quotes will be considered
> 	 * literal quotes. Example:
> 	 *
> 	 * "The month is" F       => The month is January
> 	 * i's"                   => 20'11"
> 	 *
> 	 * Backslash escaping is also supported.
> 	 *
> 	 * Input timestamp is assumed to be pre-normalized to the desired local
> 	 * time zone, if any. Note that the format characters crUeIOPTZ will assume
> 	 * $ts is UTC if $zone is not given.
> 	 *
> 	 * @param string $format
> 	 * @param string $ts 14-character timestamp
> 	 *      YYYYMMDDHHMMSS
> 	 *      01234567890123
> 	 * @param DateTimeZone $zone Timezone of $ts
> 	 * @todo handling of "o" format character for Iranian, Hebrew, Hijri & Thai?
> 	 *
> 	 * @throws MWException
> 	 * @return string
> 	 */
> 	function sprintfDate( $format, $ts, DateTimeZone $zone = null ) {
> 		$s = '';
> 		$raw = false;
> 		$roman = false;
> 		$hebrewNum = false;
> 		$dateTimeObj = false;
> 		$rawToggle = false;
> 		$iranian = false;
> 		$hebrew = false;
> 		$hijri = false;
> 		$thai = false;
> 		$minguo = false;
> 		$tenno = false;
> 
> 		if ( strlen( $ts ) !== 14 ) {
> 			throw new MWException( __METHOD__ . ": The timestamp $ts should have 14 characters" );
> 		}
> 
> 		if ( !ctype_digit( $ts ) ) {
> 			throw new MWException( __METHOD__ . ": The timestamp $ts should be a number" );
> 		}
> 
> 		$formatLength = strlen( $format );
> 		for ( $p = 0; $p < $formatLength; $p++ ) {
> 			$num = false;
> 			$code = $format[$p];
> 			if ( $code == 'x' && $p < $formatLength - 1 ) {
> 				$code .= $format[++$p];
> 			}
> 
> 			if ( ( $code === 'xi'
> 					|| $code === 'xj'
> 					|| $code === 'xk'
> 					|| $code === 'xm'
> 					|| $code === 'xo'
> 					|| $code === 'xt' )
> 				&& $p < $formatLength - 1 ) {
> 				$code .= $format[++$p];
> 			}
> 
> 			switch ( $code ) {
> 				case 'xx':
> 					$s .= 'x';
> 					break;
> 				case 'xn':
> 					$raw = true;
> 					break;
> 				case 'xN':
> 					$rawToggle = !$rawToggle;
> 					break;
> 				case 'xr':
> 					$roman = true;
> 					break;
> 				case 'xh':
> 					$hebrewNum = true;
> 					break;
> 				case 'xg':
> 					$s .= $this->getMonthNameGen( substr( $ts, 4, 2 ) );
> 					break;
> 				case 'xjx':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$s .= $this->getHebrewCalendarMonthNameGen( $hebrew[1] );
> 					break;
> 				case 'd':
> 					$num = substr( $ts, 6, 2 );
> 					break;
> 				case 'D':
> 					if ( !$dateTimeObj ) {
> 						$dateTimeObj = DateTime::createFromFormat(
> 							'YmdHis', $ts, $zone ?: new DateTimeZone( 'UTC' )
> 						);
> 					}
> 					$s .= $this->getWeekdayAbbreviation( $dateTimeObj->format( 'w' ) + 1 );
> 					break;
> 				case 'j':
> 					$num = intval( substr( $ts, 6, 2 ) );
> 					break;
> 				case 'xij':
> 					if ( !$iranian ) {
> 						$iranian = self::tsToIranian( $ts );
> 					}
> 					$num = $iranian[2];
> 					break;
> 				case 'xmj':
> 					if ( !$hijri ) {
> 						$hijri = self::tsToHijri( $ts );
> 					}
> 					$num = $hijri[2];
> 					break;
> 				case 'xjj':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$num = $hebrew[2];
> 					break;
> 				case 'l':
> 					if ( !$dateTimeObj ) {
> 						$dateTimeObj = DateTime::createFromFormat(
> 							'YmdHis', $ts, $zone ?: new DateTimeZone( 'UTC' )
> 						);
> 					}
> 					$s .= $this->getWeekdayName( $dateTimeObj->format( 'w' ) + 1 );
> 					break;
> 				case 'F':
> 					$s .= $this->getMonthName( substr( $ts, 4, 2 ) );
> 					break;
> 				case 'xiF':
> 					if ( !$iranian ) {
> 						$iranian = self::tsToIranian( $ts );
> 					}
> 					$s .= $this->getIranianCalendarMonthName( $iranian[1] );
> 					break;
> 				case 'xmF':
> 					if ( !$hijri ) {
> 						$hijri = self::tsToHijri( $ts );
> 					}
> 					$s .= $this->getHijriCalendarMonthName( $hijri[1] );
> 					break;
> 				case 'xjF':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$s .= $this->getHebrewCalendarMonthName( $hebrew[1] );
> 					break;
> 				case 'm':
> 					$num = substr( $ts, 4, 2 );
> 					break;
> 				case 'M':
> 					$s .= $this->getMonthAbbreviation( substr( $ts, 4, 2 ) );
> 					break;
> 				case 'n':
> 					$num = intval( substr( $ts, 4, 2 ) );
> 					break;
> 				case 'xin':
> 					if ( !$iranian ) {
> 						$iranian = self::tsToIranian( $ts );
> 					}
> 					$num = $iranian[1];
> 					break;
> 				case 'xmn':
> 					if ( !$hijri ) {
> 						$hijri = self::tsToHijri ( $ts );
> 					}
> 					$num = $hijri[1];
> 					break;
> 				case 'xjn':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$num = $hebrew[1];
> 					break;
> 				case 'xjt':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$num = $hebrew[3];
> 					break;
> 				case 'Y':
> 					$num = substr( $ts, 0, 4 );
> 					break;
> 				case 'xiY':
> 					if ( !$iranian ) {
> 						$iranian = self::tsToIranian( $ts );
> 					}
> 					$num = $iranian[0];
> 					break;
> 				case 'xmY':
> 					if ( !$hijri ) {
> 						$hijri = self::tsToHijri( $ts );
> 					}
> 					$num = $hijri[0];
> 					break;
> 				case 'xjY':
> 					if ( !$hebrew ) {
> 						$hebrew = self::tsToHebrew( $ts );
> 					}
> 					$num = $hebrew[0];
> 					break;
> 				case 'xkY':
> 					if ( !$thai ) {
> 						$thai = self::tsToYear( $ts, 'thai' );
> 					}
> 					$num = $thai[0];
> 					break;
> 				case 'xoY':
> 					if ( !$minguo ) {
> 						$minguo = self::tsToYear( $ts, 'minguo' );
> 					}
> 					$num = $minguo[0];
> 					break;
> 				case 'xtY':
> 					if ( !$tenno ) {
> 						$tenno = self::tsToYear( $ts, 'tenno' );
> 					}
> 					$num = $tenno[0];
> 					break;
> 				case 'y':
> 					$num = substr( $ts, 2, 2 );
> 					break;
> 				case 'xiy':
> 					if ( !$iranian ) {
> 						$iranian = self::tsToIranian( $ts );
> 					}
> 					$num = substr( $iranian[0], -2 );
> 					break;
> 				case 'a':
> 					$s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'am' : 'pm';
> 					break;
> 				case 'A':
> 					$s .= intval( substr( $ts, 8, 2 ) ) < 12 ? 'AM' : 'PM';
> 					break;
> 				case 'g':
> 					$h = substr( $ts, 8, 2 );
> 					$num = $h % 12 ? $h % 12 : 12;
> 					break;
> 				case 'G':
> 					$num = intval( substr( $ts, 8, 2 ) );
> 					break;
> 				case 'h':
> 					$h = substr( $ts, 8, 2 );
> 					$num = sprintf( '%02d', $h % 12 ? $h % 12 : 12 );
> 					break;
> 				case 'H':
> 					$num = substr( $ts, 8, 2 );
> 					break;
> 				case 'i':
> 					$num = substr( $ts, 10, 2 );
> 					break;
> 				case 's':
> 					$num = substr( $ts, 12, 2 );
> 					break;
> 				case 'c':
> 				case 'r':
> 				case 'e':
> 				case 'O':
> 				case 'P':
> 				case 'T':
> 					// Pass through string from $dateTimeObj->format()
> 					if ( !$dateTimeObj ) {
> 						$dateTimeObj = DateTime::createFromFormat(
> 							'YmdHis', $ts, $zone ?: new DateTimeZone( 'UTC' )
> 						);
> 					}
> 					$s .= $dateTimeObj->format( $code );
> 					break;
> 				case 'w':
> 				case 'N':
> 				case 'z':
> 				case 'W':
> 				case 't':
> 				case 'L':
> 				case 'o':
> 				case 'U':
> 				case 'I':
> 				case 'Z':
> 					// Pass through number from $dateTimeObj->format()
> 					if ( !$dateTimeObj ) {
> 						$dateTimeObj = DateTime::createFromFormat(
> 							'YmdHis', $ts, $zone ?: new DateTimeZone( 'UTC' )
> 						);
> 					}
> 					$num = $dateTimeObj->format( $code );
> 					break;
> 				case '\\':
> 					# Backslash escaping
> 					if ( $p < $formatLength - 1 ) {
> 						$s .= $format[++$p];
> 					} else {
> 						$s .= '\\';
> 					}
> 					break;
> 				case '"':
> 					# Quoted literal
> 					if ( $p < $formatLength - 1 ) {
> 						$endQuote = strpos( $format, '"', $p + 1 );
> 						if ( $endQuote === false ) {
> 							# No terminating quote, assume literal "
> 							$s .= '"';
> 						} else {
> 							$s .= substr( $format, $p + 1, $endQuote - $p - 1 );
> 							$p = $endQuote;
> 						}
> 					} else {
> 						# Quote at end of string, assume literal "
> 						$s .= '"';
> 					}
> 					break;
> 				default:
> 					$s .= $format[$p];
> 			}
> 			if ( $num !== false ) {
> 				if ( $rawToggle || $raw ) {
> 					$s .= $num;
> 					$raw = false;
> 				} elseif ( $roman ) {
> 					$s .= Language::romanNumeral( $num );
> 					$roman = false;
> 				} elseif ( $hebrewNum ) {
> 					$s .= self::hebrewNumeral( $num );
> 					$hebrewNum = false;
> 				} else {
> 					$s .= $this->formatNum( $num, true );
> 				}
> 			}
> 		}
> 
> 		return $s;
> 	}
> 
> 	private static $GREG_DAYS = array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
> 	private static $IRANIAN_DAYS = array( 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 );
> 
> 	/**
> 	 * Algorithm by Roozbeh Pournader and Mohammad Toossi to convert
> 	 * Gregorian dates to Iranian dates. Originally written in C, it
> 	 * is released under the terms of GNU Lesser General Public
> 	 * License. Conversion to PHP was performed by Niklas Laxström.
> 	 *
> 	 * Link: http://www.farsiweb.info/jalali/jalali.c
> 	 *
> 	 * @param string $ts
> 	 *
> 	 * @return string
> 	 */
> 	private static function tsToIranian( $ts ) {
> 		$gy = substr( $ts, 0, 4 ) -1600;
> 		$gm = substr( $ts, 4, 2 ) -1;
> 		$gd = substr( $ts, 6, 2 ) -1;
> 
> 		# Days passed from the beginning (including leap years)
> 		$gDayNo = 365 * $gy
> 			+ floor( ( $gy + 3 ) / 4 )
> 			- floor( ( $gy + 99 ) / 100 )
> 			+ floor( ( $gy + 399 ) / 400 );
> 
> 		// Add days of the past months of this year
> 		for ( $i = 0; $i < $gm; $i++ ) {
> 			$gDayNo += self::$GREG_DAYS[$i];
> 		}
> 
> 		// Leap years
> 		if ( $gm > 1 && ( ( $gy % 4 === 0 && $gy % 100 !== 0 || ( $gy % 400 == 0 ) ) ) ) {
> 			$gDayNo++;
> 		}
> 
> 		// Days passed in current month
> 		$gDayNo += (int)$gd;
> 
> 		$jDayNo = $gDayNo - 79;
> 
> 		$jNp = floor( $jDayNo / 12053 );
> 		$jDayNo %= 12053;
> 
> 		$jy = 979 + 33 * $jNp + 4 * floor( $jDayNo / 1461 );
> 		$jDayNo %= 1461;
> 
> 		if ( $jDayNo >= 366 ) {
> 			$jy += floor( ( $jDayNo - 1 ) / 365 );
> 			$jDayNo = floor( ( $jDayNo - 1 ) % 365 );
> 		}
> 
> 		for ( $i = 0; $i < 11 && $jDayNo >= self::$IRANIAN_DAYS[$i]; $i++ ) {
> 			$jDayNo -= self::$IRANIAN_DAYS[$i];
> 		}
> 
> 		$jm = $i + 1;
> 		$jd = $jDayNo + 1;
> 
> 		return array( $jy, $jm, $jd );
> 	}
> 
> 	/**
> 	 * Converting Gregorian dates to Hijri dates.
> 	 *
> 	 * Based on a PHP-Nuke block by Sharjeel which is released under GNU/GPL license
> 	 *
> 	 * @see http://phpnuke.org/modules.php?name=News&file=article&sid=8234&mode=thread&order=0&thold=0
> 	 *
> 	 * @param string $ts
> 	 *
> 	 * @return string
> 	 */
> 	private static function tsToHijri( $ts ) {
> 		$year = substr( $ts, 0, 4 );
> 		$month = substr( $ts, 4, 2 );
> 		$day = substr( $ts, 6, 2 );
> 
> 		$zyr = $year;
> 		$zd = $day;
> 		$zm = $month;
> 		$zy = $zyr;
> 
> 		if (
> 			( $zy > 1582 ) || ( ( $zy == 1582 ) && ( $zm > 10 ) ) ||
> 			( ( $zy == 1582 ) && ( $zm == 10 ) && ( $zd > 14 ) )
> 		) {
> 			$zjd = (int)( ( 1461 * ( $zy + 4800 + (int)( ( $zm - 14 ) / 12 ) ) ) / 4 ) +
> 					(int)( ( 367 * ( $zm - 2 - 12 * ( (int)( ( $zm - 14 ) / 12 ) ) ) ) / 12 ) -
> 					(int)( ( 3 * (int)( ( ( $zy + 4900 + (int)( ( $zm - 14 ) / 12 ) ) / 100 ) ) ) / 4 ) +
> 					$zd - 32075;
> 		} else {
> 			$zjd = 367 * $zy - (int)( ( 7 * ( $zy + 5001 + (int)( ( $zm - 9 ) / 7 ) ) ) / 4 ) +
> 								(int)( ( 275 * $zm ) / 9 ) + $zd + 1729777;
> 		}
> 
> 		$zl = $zjd -1948440 + 10632;
> 		$zn = (int)( ( $zl - 1 ) / 10631 );
> 		$zl = $zl - 10631 * $zn + 354;
> 		$zj = ( (int)( ( 10985 - $zl ) / 5316 ) ) * ( (int)( ( 50 * $zl ) / 17719 ) ) +
> 			( (int)( $zl / 5670 ) ) * ( (int)( ( 43 * $zl ) / 15238 ) );
> 		$zl = $zl - ( (int)( ( 30 - $zj ) / 15 ) ) * ( (int)( ( 17719 * $zj ) / 50 ) ) -
> 			( (int)( $zj / 16 ) ) * ( (int)( ( 15238 * $zj ) / 43 ) ) + 29;
> 		$zm = (int)( ( 24 * $zl ) / 709 );
> 		$zd = $zl - (int)( ( 709 * $zm ) / 24 );
> 		$zy = 30 * $zn + $zj - 30;
> 
> 		return array( $zy, $zm, $zd );
> 	}
> 
> 	/**
> 	 * Converting Gregorian dates to Hebrew dates.
> 	 *
> 	 * Based on a JavaScript code by Abu Mami and Yisrael Hersch
> 	 * (abu-mami@kaluach.net, http://www.kaluach.net), who permitted
> 	 * to translate the relevant functions into PHP and release them under
> 	 * GNU GPL.
> 	 *
> 	 * The months are counted from Tishrei = 1. In a leap year, Adar I is 13
> 	 * and Adar II is 14. In a non-leap year, Adar is 6.
> 	 *
> 	 * @param string $ts
> 	 *
> 	 * @return string
> 	 */
> 	private static function tsToHebrew( $ts ) {
> 		# Parse date
> 		$year = substr( $ts, 0, 4 );
> 		$month = substr( $ts, 4, 2 );
> 		$day = substr( $ts, 6, 2 );
> 
> 		# Calculate Hebrew year
> 		$hebrewYear = $year + 3760;
> 
> 		# Month number when September = 1, August = 12
> 		$month += 4;
> 		if ( $month > 12 ) {
> 			# Next year
> 			$month -= 12;
> 			$year++;
> 			$hebrewYear++;
> 		}
> 
> 		# Calculate day of year from 1 September
> 		$dayOfYear = $day;
> 		for ( $i = 1; $i < $month; $i++ ) {
> 			if ( $i == 6 ) {
> 				# February
> 				$dayOfYear += 28;
> 				# Check if the year is leap
> 				if ( $year % 400 == 0 || ( $year % 4 == 0 && $year % 100 > 0 ) ) {
> 					$dayOfYear++;
> 				}
> 			} elseif ( $i == 8 || $i == 10 || $i == 1 || $i == 3 ) {
> 				$dayOfYear += 30;
> 			} else {
> 				$dayOfYear += 31;
> 			}
> 		}
> 
> 		# Calculate the start of the Hebrew year
> 		$start = self::hebrewYearStart( $hebrewYear );
> 
> 		# Calculate next year's start
> 		if ( $dayOfYear <= $start ) {
> 			# Day is before the start of the year - it is the previous year
> 			# Next year's start
> 			$nextStart = $start;
> 			# Previous year
> 			$year--;
> 			$hebrewYear--;
> 			# Add days since previous year's 1 September
> 			$dayOfYear += 365;
> 			if ( ( $year % 400 == 0 ) || ( $year % 100 != 0 && $year % 4 == 0 ) ) {
> 				# Leap year
> 				$dayOfYear++;
> 			}
> 			# Start of the new (previous) year
> 			$start = self::hebrewYearStart( $hebrewYear );
> 		} else {
> 			# Next year's start
> 			$nextStart = self::hebrewYearStart( $hebrewYear + 1 );
> 		}
> 
> 		# Calculate Hebrew day of year
> 		$hebrewDayOfYear = $dayOfYear - $start;
> 
> 		# Difference between year's days
> 		$diff = $nextStart - $start;
> 		# Add 12 (or 13 for leap years) days to ignore the difference between
> 		# Hebrew and Gregorian year (353 at least vs. 365/6) - now the
> 		# difference is only about the year type
> 		if ( ( $year % 400 == 0 ) || ( $year % 100 != 0 && $year % 4 == 0 ) ) {
> 			$diff += 13;
> 		} else {
> 			$diff += 12;
> 		}
> 
> 		# Check the year pattern, and is leap year
> 		# 0 means an incomplete year, 1 means a regular year, 2 means a complete year
> 		# This is mod 30, to work on both leap years (which add 30 days of Adar I)
> 		# and non-leap years
> 		$yearPattern = $diff % 30;
> 		# Check if leap year
> 		$isLeap = $diff >= 30;
> 
> 		# Calculate day in the month from number of day in the Hebrew year
> 		# Don't check Adar - if the day is not in Adar, we will stop before;
> 		# if it is in Adar, we will use it to check if it is Adar I or Adar II
> 		$hebrewDay = $hebrewDayOfYear;
> 		$hebrewMonth = 1;
> 		$days = 0;
> 		while ( $hebrewMonth <= 12 ) {
> 			# Calculate days in this month
> 			if ( $isLeap && $hebrewMonth == 6 ) {
> 				# Adar in a leap year
> 				if ( $isLeap ) {
> 					# Leap year - has Adar I, with 30 days, and Adar II, with 29 days
> 					$days = 30;
> 					if ( $hebrewDay <= $days ) {
> 						# Day in Adar I
> 						$hebrewMonth = 13;
> 					} else {
> 						# Subtract the days of Adar I
> 						$hebrewDay -= $days;
> 						# Try Adar II
> 						$days = 29;
> 						if ( $hebrewDay <= $days ) {
> 							# Day in Adar II
> 							$hebrewMonth = 14;
> 						}
> 					}
> 				}
> 			} elseif ( $hebrewMonth == 2 && $yearPattern == 2 ) {
> 				# Cheshvan in a complete year (otherwise as the rule below)
> 				$days = 30;
> 			} elseif ( $hebrewMonth == 3 && $yearPattern == 0 ) {
> 				# Kislev in an incomplete year (otherwise as the rule below)
> 				$days = 29;
> 			} else {
> 				# Odd months have 30 days, even have 29
> 				$days = 30 - ( $hebrewMonth - 1 ) % 2;
> 			}
> 			if ( $hebrewDay <= $days ) {
> 				# In the current month
> 				break;
> 			} else {
> 				# Subtract the days of the current month
> 				$hebrewDay -= $days;
> 				# Try in the next month
> 				$hebrewMonth++;
> 			}
> 		}
> 
> 		return array( $hebrewYear, $hebrewMonth, $hebrewDay, $days );
> 	}
> 
> 	/**
> 	 * This calculates the Hebrew year start, as days since 1 September.
> 	 * Based on Carl Friedrich Gauss algorithm for finding Easter date.
> 	 * Used for Hebrew date.
> 	 *
> 	 * @param int $year
> 	 *
> 	 * @return string
> 	 */
> 	private static function hebrewYearStart( $year ) {
> 		$a = intval( ( 12 * ( $year - 1 ) + 17 ) % 19 );
> 		$b = intval( ( $year - 1 ) % 4 );
> 		$m = 32.044093161144 + 1.5542417966212 * $a + $b / 4.0 - 0.0031777940220923 * ( $year - 1 );
> 		if ( $m < 0 ) {
> 			$m--;
> 		}
> 		$Mar = intval( $m );
> 		if ( $m < 0 ) {
> 			$m++;
> 		}
> 		$m -= $Mar;
> 
> 		$c = intval( ( $Mar + 3 * ( $year - 1 ) + 5 * $b + 5 ) % 7 );
> 		if ( $c == 0 && $a > 11 && $m >= 0.89772376543210 ) {
> 			$Mar++;
> 		} elseif ( $c == 1 && $a > 6 && $m >= 0.63287037037037 ) {
> 			$Mar += 2;
> 		} elseif ( $c == 2 || $c == 4 || $c == 6 ) {
> 			$Mar++;
> 		}
> 
> 		$Mar += intval( ( $year - 3761 ) / 100 ) - intval( ( $year - 3761 ) / 400 ) - 24;
> 		return $Mar;
> 	}
> 
> 	/**
> 	 * Algorithm to convert Gregorian dates to Thai solar dates,
> 	 * Minguo dates or Minguo dates.
> 	 *
> 	 * Link: http://en.wikipedia.org/wiki/Thai_solar_calendar
> 	 *       http://en.wikipedia.org/wiki/Minguo_calendar
> 	 *       http://en.wikipedia.org/wiki/Japanese_era_name
> 	 *
> 	 * @param string $ts 14-character timestamp
> 	 * @param string $cName Calender name
> 	 * @return array Converted year, month, day
> 	 */
> 	private static function tsToYear( $ts, $cName ) {
> 		$gy = substr( $ts, 0, 4 );
> 		$gm = substr( $ts, 4, 2 );
> 		$gd = substr( $ts, 6, 2 );
> 
> 		if ( !strcmp( $cName, 'thai' ) ) {
> 			# Thai solar dates
> 			# Add 543 years to the Gregorian calendar
> 			# Months and days are identical
> 			$gy_offset = $gy + 543;
> 		} elseif ( ( !strcmp( $cName, 'minguo' ) ) || !strcmp( $cName, 'juche' ) ) {
> 			# Minguo dates
> 			# Deduct 1911 years from the Gregorian calendar
> 			# Months and days are identical
> 			$gy_offset = $gy - 1911;
> 		} elseif ( !strcmp( $cName, 'tenno' ) ) {
> 			# Nengō dates up to Meiji period
> 			# Deduct years from the Gregorian calendar
> 			# depending on the nengo periods
> 			# Months and days are identical
> 			if ( ( $gy < 1912 )
> 				|| ( ( $gy == 1912 ) && ( $gm < 7 ) )
> 				|| ( ( $gy == 1912 ) && ( $gm == 7 ) && ( $gd < 31 ) )
> 			) {
> 				# Meiji period
> 				$gy_gannen = $gy - 1868 + 1;
> 				$gy_offset = $gy_gannen;
> 				if ( $gy_gannen == 1 ) {
> 					$gy_offset = '元';
> 				}
> 				$gy_offset = '明治' . $gy_offset;
> 			} elseif (
> 				( ( $gy == 1912 ) && ( $gm == 7 ) && ( $gd == 31 ) ) ||
> 				( ( $gy == 1912 ) && ( $gm >= 8 ) ) ||
> 				( ( $gy > 1912 ) && ( $gy < 1926 ) ) ||
> 				( ( $gy == 1926 ) && ( $gm < 12 ) ) ||
> 				( ( $gy == 1926 ) && ( $gm == 12 ) && ( $gd < 26 ) )
> 			) {
> 				# Taishō period
> 				$gy_gannen = $gy - 1912 + 1;
> 				$gy_offset = $gy_gannen;
> 				if ( $gy_gannen == 1 ) {
> 					$gy_offset = '元';
> 				}
> 				$gy_offset = '大正' . $gy_offset;
> 			} elseif (
> 				( ( $gy == 1926 ) && ( $gm == 12 ) && ( $gd >= 26 ) ) ||
> 				( ( $gy > 1926 ) && ( $gy < 1989 ) ) ||
> 				( ( $gy == 1989 ) && ( $gm == 1 ) && ( $gd < 8 ) )
> 			) {
> 				# Shōwa period
> 				$gy_gannen = $gy - 1926 + 1;
> 				$gy_offset = $gy_gannen;
> 				if ( $gy_gannen == 1 ) {
> 					$gy_offset = '元';
> 				}
> 				$gy_offset = '昭和' . $gy_offset;
> 			} else {
> 				# Heisei period
> 				$gy_gannen = $gy - 1989 + 1;
> 				$gy_offset = $gy_gannen;
> 				if ( $gy_gannen == 1 ) {
> 					$gy_offset = '元';
> 				}
> 				$gy_offset = '平成' . $gy_offset;
> 			}
> 		} else {
> 			$gy_offset = $gy;
> 		}
> 
> 		return array( $gy_offset, $gm, $gd );
> 	}
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Nov 17 17:01:36 2019 UTC