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-2013 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-2013 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-2013 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.     /**
  182.      * Loads initialize values
  183.      *
  184.      * @ignore
  185.      */         
  186.     public function __construct()
  187.     {
  188.         $this->_xml simplexml_load_file(dirname(__FILE__).'/data/ArDate.xml');
  189.     }
  190.     
  191.     /**
  192.      * Setting value for $mode scalar
  193.      *      
  194.      * @param integer $mode Output mode of date function where:
  195.      *                        1) Hijri format (Islamic calendar)
  196.      *                        2) Arabic month names used in Middle East countries
  197.      *                        3) Arabic Transliteration of Gregorian month names
  198.      *                        4) Both of 2 and 3 formats together
  199.      *                        5) Libya style
  200.      *                        6) Algeria and Tunis style
  201.      *                        7) Morocco style
  202.      *                                   
  203.      * @return object $this to build a fluent interface
  204.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  205.      */
  206.     public function setMode($mode 1)
  207.     {
  208.         $mode = (int) $mode;
  209.         
  210.         if ($mode && $mode 8{
  211.             $this->_mode $mode;
  212.         }
  213.         
  214.         return $this;
  215.     }
  216.     
  217.     /**
  218.      * Getting $mode value that refer to output mode format
  219.      *               1) Hijri format (Islamic calendar)
  220.      *               2) Arabic month names used in Middle East countries
  221.      *               3) Arabic Transliteration of Gregorian month names
  222.      *               4) Both of 2 and 3 formats together
  223.      *               5) Libyan way
  224.      *                           
  225.      * @return Integer Value of $mode properity
  226.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  227.      */
  228.     public function getMode()
  229.     {
  230.         return $this->_mode;
  231.     }
  232.     
  233.     /**
  234.      * Format a local time/date in Arabic string
  235.      *      
  236.      * @param string  $format     Format string (same as PHP date function)
  237.      * @param integer $timestamp  Unix timestamp
  238.      * @param integer $correction To apply correction factor (+/- 1-2) to
  239.      *                             standard hijri calendar
  240.      *                    
  241.      * @return string Format Arabic date string according to given format string
  242.      *                 using the given integer timestamp or the current local
  243.      *                 time if no timestamp is given.
  244.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  245.      */
  246.     public function date($format$timestamp$correction 0)
  247.     {
  248.         if ($this->_mode == 1{
  249.             foreach ($this->_xml->hj_month->month as $month{
  250.                 $hj_txt_month["{$month['id']}"= (string)$month;
  251.             
  252.             
  253.             $patterns     array();
  254.             $replacements array();
  255.             
  256.             array_push($patterns'Y');
  257.             array_push($replacements'x1');
  258.             array_push($patterns'y');
  259.             array_push($replacements'x2');
  260.             array_push($patterns'M');
  261.             array_push($replacements'x3');
  262.             array_push($patterns'F');
  263.             array_push($replacements'x3');
  264.             array_push($patterns'n');
  265.             array_push($replacements'x4');
  266.             array_push($patterns'm');
  267.             array_push($replacements'x5');
  268.             array_push($patterns'j');
  269.             array_push($replacements'x6');
  270.             array_push($patterns'd');
  271.             array_push($replacements'x7');
  272.             
  273.             $format str_replace($patterns$replacements$format);
  274.             
  275.             $str date($format$timestamp);
  276.             $str $this->en2ar($str);
  277.  
  278.             $timestamp       $timestamp 3600*24*$correction;
  279.             list($Y$M$Dexplode(' 'date('Y m d'$timestamp));
  280.             
  281.             list($hj_y$hj_m$hj_d$this->hjConvert($Y$M$D);
  282.             
  283.             $patterns     array();
  284.             $replacements array();
  285.             
  286.             array_push($patterns'x1');
  287.             array_push($replacements$hj_y);
  288.             array_push($patterns'x2');
  289.             array_push($replacementssubstr($hj_y-2));
  290.             array_push($patterns'x3');
  291.             array_push($replacements$hj_txt_month[$hj_m]);
  292.             array_push($patterns'x4');
  293.             array_push($replacements$hj_m);
  294.             array_push($patterns'x5');
  295.             array_push($replacementssprintf('%02d'$hj_m));
  296.             array_push($patterns'x6');
  297.             array_push($replacements$hj_d);
  298.             array_push($patterns'x7');
  299.             array_push($replacementssprintf('%02d'$hj_d));
  300.             
  301.             $str str_replace($patterns$replacements$str);
  302.         elseif ($this->_mode == 5{
  303.             $year  date('Y'$timestamp);
  304.             $year -= 632;
  305.             $yr    substr("$year"-2);
  306.             
  307.             $format str_replace('Y'$year$format);
  308.             $format str_replace('y'$yr$format);
  309.             
  310.             $str date($format$timestamp);
  311.             $str $this->en2ar($str);
  312.  
  313.         else {
  314.             $str date($format$timestamp);
  315.             $str $this->en2ar($str);
  316.         }
  317.         
  318.         if (0{
  319.             if ($outputCharset == null
  320.                 $outputCharset $main->getOutputCharset()
  321.             }
  322.             $str $main->coreConvert($str'utf-8'$outputCharset);
  323.         }
  324.  
  325.         return $str;
  326.     }
  327.     
  328.     /**
  329.      * Translate English date/time terms into Arabic langauge
  330.      *      
  331.      * @param string $str Date/time string using English terms
  332.      *      
  333.      * @return string Date/time string using Arabic terms
  334.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  335.      */
  336.     protected function en2ar($str)
  337.     {
  338.         $patterns     array();
  339.         $replacements array();
  340.         
  341.         $str strtolower($str);
  342.         
  343.         foreach ($this->_xml->xpath("//en_day/mode[@id='full']/search"as $day{
  344.             array_push($patterns(string)$day);
  345.         
  346.  
  347.         foreach ($this->_xml->ar_day->replace as $day{
  348.             array_push($replacements(string)$day);
  349.         
  350.  
  351.         foreach (
  352.             $this->_xml->xpath("//en_month/mode[@id='full']/search"as $month
  353.         {
  354.             array_push($patterns(string)$month);
  355.         
  356.  
  357.         $replacements array_merge(
  358.             $replacements
  359.             $this->arabicMonths($this->_mode)
  360.         );
  361.         
  362.         foreach ($this->_xml->xpath("//en_day/mode[@id='short']/search"as $day{
  363.             array_push($patterns(string)$day);
  364.         
  365.  
  366.         foreach ($this->_xml->ar_day->replace as $day{
  367.             array_push($replacements(string)$day);
  368.         
  369.  
  370.         foreach ($this->_xml->xpath("//en_month/mode[@id='short']/search"as $m{
  371.             array_push($patterns(string)$m);
  372.         
  373.         
  374.         $replacements array_merge(
  375.             $replacements
  376.             $this->arabicMonths($this->_mode)
  377.         );
  378.     
  379.         foreach (
  380.             $this->_xml->xpath("//preg_replace[@function='en2ar']/pair"as $p
  381.         {
  382.             array_push($patterns(string)$p->search);
  383.             array_push($replacements(string)$p->replace);
  384.         
  385.  
  386.         $str str_replace($patterns$replacements$str);
  387.         
  388.         return $str;
  389.     }
  390.  
  391.     /**
  392.      * Add Arabic month names to the replacement array
  393.      *      
  394.      * @param integer $mode Naming mode of months in Arabic where:
  395.      *                        2) Arabic month names used in Middle East countries
  396.      *                        3) Arabic Transliteration of Gregorian month names
  397.      *                        4) Both of 2 and 3 formats together
  398.      *                        5) Libya style
  399.      *                        6) Algeria and Tunis style
  400.      *                        7) Morocco style
  401.      *                                   
  402.      * @return array Arabic month names in selected style
  403.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  404.      */
  405.     protected function arabicMonths($mode)
  406.     {
  407.         $replacements array();
  408.  
  409.         foreach (
  410.             $this->_xml->xpath("//ar_month/mode[@id=$mode]/replace"as $month
  411.         {
  412.             array_push($replacements(string)$month);
  413.         
  414.  
  415.         return $replacements;
  416.     }
  417.     
  418.     /**
  419.      * Convert given Gregorian date into Hijri date
  420.      *      
  421.      * @param integer $Y Year Gregorian year
  422.      * @param integer $M Month Gregorian month
  423.      * @param integer $D Day Gregorian day
  424.      *      
  425.      * @return array Hijri date [int Year, int Month, int Day](Islamic calendar)
  426.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  427.      */
  428.     protected function hjConvert($Y$M$D)
  429.     {
  430.         if (function_exists('GregorianToJD')) {
  431.             $jd GregorianToJD($M$D$Y);
  432.         else {
  433.             $jd $this->gregToJd($M$D$Y);
  434.         }
  435.         
  436.         list($year$month$day$this->jdToIslamic($jd);
  437.         
  438.         return array($year$month$day);
  439.     }
  440.     
  441.     /**
  442.      * Convert given Julian day into Hijri date
  443.      *      
  444.      * @param integer $jd Julian day
  445.      *      
  446.      * @return array Hijri date [int Year, int Month, int Day](Islamic calendar)
  447.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  448.      */
  449.     protected function jdToIslamic($jd)
  450.     {
  451.         $l = (int)$jd 1948440 10632;
  452.         $n = (int)(($l 110631);
  453.         $l $l 10631 $n 354;
  454.         $j = (int)((10985 $l5316* (int)((50 $l17719
  455.             + (int)($l 5670* (int)((43 $l15238);
  456.         $l $l - (int)((30 $j15* (int)((17719 $j50
  457.             - (int)($j 16* (int)((15238 $j4329;
  458.         $m = (int)((24 $l709);
  459.         $d $l - (int)((709 $m24);
  460.         $y = (int)(30 $n $j 30);
  461.         
  462.         return array($y$m$d);
  463.     }
  464.     
  465.     /**
  466.      * Convert given Hijri date into Julian day
  467.      *      
  468.      * @param integer $year  Year Hijri year
  469.      * @param integer $month Month Hijri month
  470.      * @param integer $day   Day Hijri day
  471.      *      
  472.      * @return integer Julian day
  473.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  474.      */
  475.     protected function islamicToJd($year$month$day)
  476.     {
  477.         $jd = (int)((11 $year 330+ (int)(354 $year+ (int)(30 $month
  478.             - (int)(($month 12$day 1948440 385;
  479.         return $jd;
  480.     }
  481.     
  482.     /**
  483.      * Converts a Gregorian date to Julian Day Count
  484.      *      
  485.      * @param integer $m The month as a number from 1 (for January)
  486.      *                    to 12 (for December)
  487.      * @param integer $d The day as a number from 1 to 31
  488.      * @param integer $y The year as a number between -4714 and 9999
  489.      *       
  490.      * @return integer The julian day for the given gregorian date as an integer
  491.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  492.      */
  493.     protected function gregToJd ($m$d$y)
  494.     {
  495.         if ($m 3{
  496.             $y--;
  497.             $m += 12;
  498.         }
  499.         
  500.         if (($y 1582|| ($y == 1582 && $m 10
  501.             || ($y == 1582 && $m == 10 && $d <= 15)
  502.         {
  503.             // This is ignored in the GregorianToJD PHP function!
  504.             $b 0;
  505.         else {
  506.             $a = (int)($y 100);
  507.             $b $a + (int)($a 4);
  508.         }
  509.         
  510.         $jd = (int)(365.25 ($y 4716)) + (int)(30.6001 ($m 1)) 
  511.             + $d $b 1524.5;
  512.         
  513.         return round($jd);
  514.     }
  515.  
  516.     /**
  517.      * Calculate Hijri calendar correction using Um-Al-Qura calendar information
  518.      *      
  519.      * @param integer $time Unix timestamp
  520.      *       
  521.      * @return integer Correction factor to fix Hijri calendar calculation using
  522.      *                  Um-Al-Qura calendar information
  523.      * @author Khaled Al-Sham'aa <khaled@ar-php.org>
  524.      */
  525.     public function dateCorrection ($time)
  526.     {
  527.         $calc $time $this->date('j'$time3600 24;
  528.         
  529.         $file dirname(__FILE__).'/data/um_alqoura.txt';
  530.  
  531.         $content file_get_contents($file);
  532.  
  533.         $y      $this->date('Y'$time);
  534.         $m      $this->date('n'$time);
  535.         $offset (($y-142012 $m11;
  536.         
  537.         $d substr($content$offset2);
  538.         $m substr($content$offset+32);
  539.         $y substr($content$offset+64);
  540.         
  541.         $real mktime(000$m$d$y);
  542.         
  543.         $diff = (int)(($calc $real(3600 24));
  544.         
  545.         return $diff;
  546.     }
  547. }

Documentation generated on Mon, 14 Jan 2013 17:48:44 +0100 by phpDocumentor 1.4.0