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

Documentation generated on Fri, 01 Jan 2016 10:25:57 +0200 by phpDocumentor 1.4.0