I18N_Arabic
[ class tree: I18N_Arabic ] [ index: I18N_Arabic ] [ all elements ]

Source for file Date.php

Documentation is available at Date.php

  1. <?php
  2. /**
  3.  * ----------------------------------------------------------------------
  4.  *  
  5.  * Copyright (c) 2006-2012 Khaled Al-Sham'aa.
  6.  *  
  7.  * http://www.ar-php.org
  8.  *  
  9.  * PHP Version 5
  10.  *  
  11.  * ----------------------------------------------------------------------
  12.  *  
  13.  * LICENSE
  14.  *
  15.  * This program is open source product; you can redistribute it and/or
  16.  * modify it under the terms of the GNU Lesser General Public License (LGPL)
  17.  * as published by the Free Software Foundation; either version 3
  18.  * of the License, or (at your option) any later version.
  19.  *  
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU Lesser General Public License for more details.
  24.  *  
  25.  * You should have received a copy of the GNU Lesser General Public License
  26.  * along with this program.  If not, see <http://www.gnu.org/licenses/lgpl.txt>.
  27.  *  
  28.  * ----------------------------------------------------------------------
  29.  *  
  30.  * Class Name: Arabic Date
  31.  *  
  32.  * Filename:   Date.php
  33.  *  
  34.  * Original    Author(s): Khaled Al-Sham'aa <khaled@ar-php.org>
  35.  *  
  36.  * Purpose:    Arabic customization for PHP date function
  37.  *  
  38.  * ----------------------------------------------------------------------
  39.  *  
  40.  * Arabic Date
  41.  *
  42.  * PHP class for Arabic and Islamic customization of PHP date function. It
  43.  * can convert UNIX timestamp into string in Arabic as well as convert it into
  44.  * Hijri calendar
  45.  * 
  46.  * The Islamic Calendar:
  47.  * 
  48.  * The Islamic calendar is purely lunar and consists of twelve alternating months
  49.  * of 30 and 29 days, with the final 29 day month extended to 30 days during leap
  50.  * years. Leap years follow a 30 year cycle and occur in years 1, 5, 7, 10, 13, 16,
  51.  * 18, 21, 24, 26, and 29. The calendar begins on Friday, July 16th, 622 C.E. in
  52.  * the Julian calendar, Julian day 1948439.5, the day of Muhammad's separate from
  53.  * Mecca to Medina, the first day of the first month of year 1 A.H.--"Anno Hegira".
  54.  * 
  55.  * Each cycle of 30 years thus contains 19 normal years of 354 days and 11 leap
  56.  * years of 355, so the average length of a year is therefore
  57.  * ((19 x 354) + (11 x 355)) / 30 = 354.365... days, with a mean length of month of
  58.  * 1/12 this figure, or 29.53055... days, which closely approximates the mean
  59.  * synodic month (time from new Moon to next new Moon) of 29.530588 days, with the
  60.  * calendar only slipping one day with respect to the Moon every 2525 years. Since
  61.  * the calendar is fixed to the Moon, not the solar year, the months shift with
  62.  * respect to the seasons, with each month beginning about 11 days earlier in each
  63.  * successive solar year.
  64.  * 
  65.  * The convert presented here is the most commonly used civil calendar in the
  66.  * Islamic world; for religious purposes months are defined to start with the
  67.  * first observation of the crescent of the new Moon.
  68.  * 
  69.  * The Julian Calendar:
  70.  * 
  71.  * The Julian calendar was proclaimed by Julius Casar in 46 B.C. and underwent
  72.  * several modifications before reaching its final form in 8 C.E. The Julian
  73.  * calendar differs from the Gregorian only in the determination of leap years,
  74.  * lacking the correction for years divisible by 100 and 400 in the Gregorian
  75.  * calendar. In the Julian calendar, any positive year is a leap year if divisible
  76.  * by 4. (Negative years are leap years if when divided by 4 a remainder of 3
  77.  * results.) Days are considered to begin at midnight.
  78.  * 
  79.  * In the Julian calendar the average year has a length of 365.25 days. compared to
  80.  * the actual solar tropical year of 365.24219878 days. The calendar thus
  81.  * accumulates one day of error with respect to the solar year every 128 years.
  82.  * Being a purely solar calendar, no attempt is made to synchronise the start of
  83.  * months to the phases of the Moon.
  84.  * 
  85.  * The Gregorian Calendar:
  86.  * 
  87.  * The Gregorian calendar was proclaimed by Pope Gregory XIII and took effect in
  88.  * most Catholic states in 1582, in which October 4, 1582 of the Julian calendar
  89.  * was followed by October 15 in the new calendar, correcting for the accumulated
  90.  * discrepancy between the Julian calendar and the equinox as of that date. When
  91.  * comparing historical dates, it's important to note that the Gregorian calendar,
  92.  * used universally today in Western countries and in international commerce, was
  93.  * adopted at different times by different countries. Britain and her colonies
  94.  * (including what is now the United States), did not switch to the Gregorian
  95.  * calendar until 1752, when Wednesday 2nd September in the Julian calendar dawned
  96.  * as Thursday the 14th in the Gregorian.
  97.  * 
  98.  * The Gregorian calendar is a minor correction to the Julian. In the Julian
  99.  * calendar every fourth year is a leap year in which February has 29, not 28 days,
  100.  * but in the Gregorian, years divisible by 100 are not leap years unless they are
  101.  * also divisible by 400. How prescient was Pope Gregory! Whatever the problems of
  102.  * Y2K, they won't include sloppy programming which assumes every year divisible by
  103.  * 4 is a leap year since 2000, unlike the previous and subsequent years divisible
  104.  * by 100, is a leap year. As in the Julian calendar, days are considered to begin
  105.  * at midnight.
  106.  * 
  107.  * The average length of a year in the Gregorian calendar is 365.2425 days compared
  108.  * to the actual solar tropical year (time from equinox to equinox) of 365.24219878
  109.  * days, so the calendar accumulates one day of error with respect to the solar year
  110.  * about every 3300 years. As a purely solar calendar, no attempt is made to
  111.  * synchronise the start of months to the phases of the Moon.
  112.  * 
  113.  * date -- Format a local time/date
  114.  * string date ( string format, int timestamp);
  115.  * 
  116.  * Returns a string formatted according to the given format string using the given
  117.  * integer timestamp or the current local time if no timestamp is given. In
  118.  * otherwords, timestamp is optional and defaults to the value of time().
  119.  * 
  120.  * Example:
  121.  * <code>
  122.  *   date_default_timezone_set('UTC');
  123.  *   $time = time();
  124.  *   
  125.  *   echo date('l dS F Y h:i:s A', $time);
  126.  *   echo '<br /><br />';
  127.  *   
  128.  *   include('./I18N/Arabic.php');
  129.  *   $obj = new I18N_Arabic('Date');
  130.  *   
  131.  *   echo $obj->date('l dS F Y h:i:s A', $time);
  132.  *   echo '<br /><br />';
  133.  *   
  134.  *   $obj->setMode(2);
  135.  *   echo $obj->date('l dS F Y h:i:s A', $time);
  136.  *   echo '<br /><br />';
  137.  *   
  138.  *   $obj->setMode(3);
  139.  *   echo $obj->date('l dS F Y h:i:s A', $time);
  140.  *   echo '<br /><br />';
  141.  *   
  142.  *   $obj->setMode(4);
  143.  *   echo $obj->date('l dS F Y h:i:s A', $time);
  144.  * </code>
  145.  *                 
  146.  * @category  I18N
  147.  * @package   I18N_Arabic
  148.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  149.  * @copyright 2006-2012 Khaled Al-Sham'aa
  150.  *    
  151.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  152.  * @link      http://www.ar-php.org
  153.  */
  154.  
  155. // New in PHP V5.3: Namespaces
  156. // namespace I18N\Arabic;
  157. // 
  158. // $obj = new I18N\Arabic\Date();
  159. // 
  160. // use I18N\Arabic;
  161. // $obj = new Arabic\Date();
  162. //
  163. // use I18N\Arabic\Date as Date;
  164. // $obj = new Date();
  165.  
  166. /**
  167.  * This PHP class is an Arabic customization for PHP date function
  168.  *  
  169.  * @category  I18N
  170.  * @package   I18N_Arabic
  171.  * @author    Khaled Al-Sham'aa <khaled@ar-php.org>
  172.  * @copyright 2006-2012 Khaled Al-Sham'aa
  173.  *    
  174.  * @license   LGPL <http://www.gnu.org/licenses/lgpl.txt>
  175.  * @link      http://www.ar-php.org
  176.  */ 
  177. {
  178.     private $_mode 1;
  179.     private $_xml  null;
  180.  
  181.     private static $_islamicEpoch 1948439.5;
  182.  
  183.     /**
  184.      * Loads initialize values
  185.      *
  186.      * @ignore
  187.      */         
  188.     public function __construct()
  189.     {
  190.         $this->_xml simplexml_load_file(dirname(__FILE__).'/data/ArDate.xml');
  191.     }
  192.     
  193.     /**
  194.      * Setting value for $mode scalar
  195.      *      
  196.      * @param integer $mode Output mode of date function where:
  197.      *                        1) Hijri format (Islamic calendar)
  198.      *                        2) Arabic month names used in Middle East countries
  199.      *                        3) Arabic Transliteration of Gregorian month names
  200.      *                        4) Both of 2 and 3 formats together
  201.      *                        5) Libya style
  202.      *                        6) Algeria and Tunis style
  203.      *                        7) Morocco style
  204.      *                                   
  205.      * @return object $this to build a fluent interface
  206.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  207.      */
  208.     public function setMode($mode 1)
  209.     {
  210.         $mode = (int) $mode;
  211.         
  212.         if ($mode && $mode 8{
  213.             $this->_mode $mode;
  214.         }
  215.         
  216.         return $this;
  217.     }
  218.     
  219.     /**
  220.      * Getting $mode value that refer to output mode format
  221.      *               1) Hijri format (Islamic calendar)
  222.      *               2) Arabic month names used in Middle East countries
  223.      *               3) Arabic Transliteration of Gregorian month names
  224.      *               4) Both of 2 and 3 formats together
  225.      *               5) Libyan way
  226.      *                           
  227.      * @return Integer Value of $mode properity
  228.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  229.      */
  230.     public function getMode()
  231.     {
  232.         return $this->_mode;
  233.     }
  234.     
  235.     /**
  236.      * Format a local time/date in Arabic string
  237.      *      
  238.      * @param string  $format     Format string (same as PHP date function)
  239.      * @param integer $timestamp  Unix timestamp
  240.      * @param integer $correction To apply correction factor (+/- 1-2) to
  241.      *                             standard hijri calendar
  242.      *                    
  243.      * @return string Format Arabic date string according to given format string
  244.      *                 using the given integer timestamp or the current local
  245.      *                 time if no timestamp is given.
  246.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  247.      */
  248.     public function date($format$timestamp$correction 0)
  249.     {
  250.         if ($this->_mode == 1{
  251.             foreach ($this->_xml->hj_month->month as $month{
  252.                 $hj_txt_month["{$month['id']}"= (string)$month;
  253.             
  254.             
  255.             $patterns     array();
  256.             $replacements array();
  257.             
  258.             array_push($patterns'Y');
  259.             array_push($replacements'x1');
  260.             array_push($patterns'y');
  261.             array_push($replacements'x2');
  262.             array_push($patterns'M');
  263.             array_push($replacements'x3');
  264.             array_push($patterns'F');
  265.             array_push($replacements'x3');
  266.             array_push($patterns'n');
  267.             array_push($replacements'x4');
  268.             array_push($patterns'm');
  269.             array_push($replacements'x5');
  270.             array_push($patterns'j');
  271.             array_push($replacements'x6');
  272.             array_push($patterns'd');
  273.             array_push($replacements'x7');
  274.             
  275.             $format str_replace($patterns$replacements$format);
  276.             
  277.             $str date($format$timestamp);
  278.             $str $this->en2ar($str);
  279.  
  280.             $timestamp       $timestamp 3600*24*$correction;
  281.             list($Y$M$Dexplode(' 'date('Y m d'$timestamp));
  282.             
  283.             list($hj_y$hj_m$hj_d$this->hjConvert($Y$M$D);
  284.             
  285.             $patterns     array();
  286.             $replacements array();
  287.             
  288.             array_push($patterns'x1');
  289.             array_push($replacements$hj_y);
  290.             array_push($patterns'x2');
  291.             array_push($replacementssubstr($hj_y-2));
  292.             array_push($patterns'x3');
  293.             array_push($replacements$hj_txt_month[$hj_m]);
  294.             array_push($patterns'x4');
  295.             array_push($replacements$hj_m);
  296.             array_push($patterns'x5');
  297.             array_push($replacementssprintf('%02d'$hj_m));
  298.             array_push($patterns'x6');
  299.             array_push($replacements$hj_d);
  300.             array_push($patterns'x7');
  301.             array_push($replacementssprintf('%02d'$hj_d));
  302.             
  303.             $str str_replace($patterns$replacements$str);
  304.         elseif ($this->_mode == 5{
  305.             $year  date('Y'$timestamp);
  306.             $year -= 632;
  307.             $yr    substr("$year"-2);
  308.             
  309.             $format str_replace('Y'$year$format);
  310.             $format str_replace('y'$yr$format);
  311.             
  312.             $str date($format$timestamp);
  313.             $str $this->en2ar($str);
  314.  
  315.         else {
  316.             $str date($format$timestamp);
  317.             $str $this->en2ar($str);
  318.         }
  319.         
  320.         if (0{
  321.             if ($outputCharset == null
  322.                 $outputCharset $main->getOutputCharset()
  323.             }
  324.             $str $main->coreConvert($str'utf-8'$outputCharset);
  325.         }
  326.  
  327.         return $str;
  328.     }
  329.     
  330.     /**
  331.      * Translate English date/time terms into Arabic langauge
  332.      *      
  333.      * @param string $str Date/time string using English terms
  334.      *      
  335.      * @return string Date/time string using Arabic terms
  336.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  337.      */
  338.     protected function en2ar($str)
  339.     {
  340.         $patterns     array();
  341.         $replacements array();
  342.         
  343.         $str strtolower($str);
  344.         
  345.         foreach ($this->_xml->xpath("//en_day/mode[@id='full']/search"as $day{
  346.             array_push($patterns(string)$day);
  347.         
  348.  
  349.         foreach ($this->_xml->ar_day->replace as $day{
  350.             array_push($replacements(string)$day);
  351.         
  352.  
  353.         foreach ($this->_xml->xpath("//en_month/mode[@id='full']/search"as $month{
  354.             array_push($patterns(string)$month);
  355.         
  356.  
  357.         $replacements array_merge($replacements$this->arabicMonths($this->_mode));
  358.         
  359.         foreach ($this->_xml->xpath("//en_day/mode[@id='short']/search"as $day{
  360.             array_push($patterns(string)$day);
  361.         
  362.  
  363.         foreach ($this->_xml->ar_day->replace as $day{
  364.             array_push($replacements(string)$day);
  365.         
  366.  
  367.         foreach ($this->_xml->xpath("//en_month/mode[@id='short']/search"as $m{
  368.             array_push($patterns(string)$m);
  369.         
  370.         
  371.         $replacements array_merge($replacements$this->arabicMonths($this->_mode));
  372.     
  373.         foreach ($this->_xml->xpath("//preg_replace[@function='en2ar']/pair"as $p{
  374.             array_push($patterns(string)$p->search);
  375.             array_push($replacements(string)$p->replace);
  376.         
  377.  
  378.         $str str_replace($patterns$replacements$str);
  379.         
  380.         return $str;
  381.     }
  382.  
  383.     /**
  384.      * Add Arabic month names to the replacement array
  385.      *      
  386.      * @param integer $mode Naming mode of months in Arabic where:
  387.      *                        2) Arabic month names used in Middle East countries
  388.      *                        3) Arabic Transliteration of Gregorian month names
  389.      *                        4) Both of 2 and 3 formats together
  390.      *                        5) Libya style
  391.      *                        6) Algeria and Tunis style
  392.      *                        7) Morocco style
  393.      *                                   
  394.      * @return array Arabic month names in selected style
  395.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  396.      */
  397.     protected function arabicMonths($mode)
  398.     {
  399.         $replacements array();
  400.  
  401.         foreach ($this->_xml->xpath("//ar_month/mode[@id=$mode]/replace"as $month{
  402.             array_push($replacements(string)$month);
  403.         
  404.  
  405.         return $replacements;
  406.     }
  407.     
  408.     /**
  409.      * Convert given Gregorian date into Hijri date
  410.      *      
  411.      * @param integer $Y Year Gregorian year
  412.      * @param integer $M Month Gregorian month
  413.      * @param integer $D Day Gregorian day
  414.      *      
  415.      * @return array Hijri date [int Year, int Month, int Day](Islamic calendar)
  416.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  417.      */
  418.     protected function hjConvert($Y$M$D)
  419.     {
  420.         // To get these functions to work, you have to compile PHP 
  421.         // with --enable-calendar 
  422.         // http://www.php.net/manual/en/calendar.installation.php
  423.         // $jd = GregorianToJD($M, $D, $Y);
  424.         
  425.         $jd $this->gregToJd($M$D$Y);
  426.         
  427.         list($year$month$day$this->jdToIslamic($jd);
  428.         
  429.         return array($year$month$day);
  430.     }
  431.     
  432.     /**
  433.      * Convert given Julian day into Hijri date
  434.      *      
  435.      * @param integer $jd Julian day
  436.      *      
  437.      * @return array Hijri date [int Year, int Month, int Day](Islamic calendar)
  438.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  439.      */
  440.     protected function jdToIslamic($jd)
  441.     {
  442.         $jd    = (int)$jd 0.5;
  443.         $year  ((30 ($jd self::$_islamicEpoch)) 1064610631;
  444.         $year  = (int)$year;
  445.         $month min(12ceil(($jd (29 $this->islamicToJd($year11))) 29.5
  446.                          + 1);
  447.         $day   ($jd $this->islamicToJd($year$month1)) 1;
  448.         
  449.         return array($year$month$day);
  450.     }
  451.     
  452.     /**
  453.      * Convert given Hijri date into Julian day
  454.      *      
  455.      * @param integer $year  Year Hijri year
  456.      * @param integer $month Month Hijri month
  457.      * @param integer $day   Day Hijri day
  458.      *      
  459.      * @return integer Julian day
  460.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  461.      */
  462.     protected function islamicToJd($year$month$day)
  463.     {
  464.         return($day ceil(29.5 ($month 1)) ($year 1354 
  465.                (int)(((11 $year)) 30self::$_islamicEpoch1;
  466.     }
  467.     
  468.     /**
  469.      * Converts a Gregorian date to Julian Day Count
  470.      *      
  471.      * @param integer $m The month as a number from 1 (for January)
  472.      *                    to 12 (for December)
  473.      * @param integer $d The day as a number from 1 to 31
  474.      * @param integer $y The year as a number between -4714 and 9999
  475.      *       
  476.      * @return integer The julian day for the given gregorian date as an integer
  477.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  478.      */
  479.     protected function gregToJd ($m$d$y)
  480.     {
  481.         if ($m 2{
  482.             $m $m 3;
  483.         else {
  484.             $m $m 9
  485.             $y $y 1;
  486.         }
  487.         
  488.         $c  $y 100
  489.         $ya $y 100 $c;
  490.         $jd (146097 $c(1461 $ya
  491.               (153 $m 2$d 1721119;
  492.         
  493.         return round($jd);
  494.     }
  495.  
  496.     /**
  497.      * Calculate Hijri calendar correction using Um-Al-Qura calendar information
  498.      *      
  499.      * @param integer $time Unix timestamp
  500.      *       
  501.      * @return integer Correction factor to fix Hijri calendar calculation using
  502.      *                  Um-Al-Qura calendar information
  503.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  504.      */
  505.     public function dateCorrection ($time)
  506.     {
  507.         $calc $time $this->date('j'$time3600 24;
  508.         
  509.         $file dirname(__FILE__).'/data/um_alqoura.txt';
  510.  
  511.         $content file_get_contents($file);
  512.  
  513.         $y      $this->date('Y'$time);
  514.         $m      $this->date('n'$time);
  515.         $offset (($y-142012 $m11;
  516.         
  517.         $d substr($content$offset2);
  518.         $m substr($content$offset+32);
  519.         $y substr($content$offset+64);
  520.         
  521.         $real mktime(000$m$d$y);
  522.         
  523.         $diff = (int)(($calc $real(3600 24));
  524.         
  525.         return $diff;
  526.     }
  527. }

Documentation generated on Wed, 29 Aug 2012 08:32:55 +0200 by phpDocumentor 1.4.0