Advertisement
Guest User

Untitled

a guest
Nov 7th, 2017
548
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 25.68 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Jalali (Shamsi) DateTime Class. Supports years higher than 2038.
  4.  *
  5.  * Copyright (c) 2012 Sallar Kaboli <sallar.kaboli@gmail.com>
  6.  * http://sallar.me
  7.  *
  8.  * The MIT License (MIT)
  9.  *
  10.  * Permission is hereby granted, free of charge, to any person obtaining a
  11.  * copy of this software and associated documentation files (the "Software"),
  12.  * to deal in the Software without restriction, including without limitation
  13.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  14.  * and/or sell copies of the Software, and to permit persons to whom the
  15.  * Software is furnished to do so, subject to the following conditions:
  16.  *
  17.  * 1- The above copyright notice and this permission notice shall be included
  18.  * in all copies or substantial portions of the Software.
  19.  *
  20.  * 2- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  21.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23.  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  26.  * DEALINGS IN THE SOFTWARE.
  27.  *
  28.  * Original Jalali to Gregorian (and vice versa) convertor:
  29.  * Copyright (C) 2000  Roozbeh Pournader and Mohammad Toossi
  30.  *
  31.  * List of supported timezones can be found here:
  32.  * http://www.php.net/manual/en/timezones.php
  33.  *
  34.  *
  35.  * @package    jDateTime
  36.  * @author     Sallar Kaboli <sallar.kaboli@gmail.com>
  37.  * @author     Omid Pilevar <omid.pixel@gmail.com>
  38.  * @copyright  2003-2012 Sallar Kaboli
  39.  * @license    http://opensource.org/licenses/mit-license.php The MIT License
  40.  * @link       https://github.com/sallar/jDateTime
  41.  * @see        DateTime
  42.  * @version    2.2.0
  43.  */
  44. class jDateTime
  45. {
  46.  
  47.     /**
  48.      * Defaults
  49.      */
  50.     private static $jalali   = true; //Use Jalali Date, If set to false, falls back to gregorian
  51.     private static $convert  = true; //Convert numbers to Farsi characters in utf-8
  52.     private static $timezone = null; //Timezone String e.g Asia/Tehran, Defaults to Server Timezone Settings
  53.     private static $temp = array();
  54.  
  55.     /**
  56.      * jDateTime::Constructor
  57.      *
  58.      * Pass these parameteres when creating a new instance
  59.      * of this Class, and they will be used as defaults.
  60.      * e.g $obj = new jDateTime(false, true, 'Asia/Tehran');
  61.      * To use system defaults pass null for each one or just
  62.      * create the object without any parameters.
  63.      *
  64.      * @author Sallar Kaboli
  65.      * @param $convert bool Converts numbers to Farsi
  66.      * @param $jalali bool Converts date to Jalali
  67.      * @param $timezone string Timezone string
  68.      */
  69.     public function __construct($convert = null, $jalali = null, $timezone = null)
  70.     {
  71.         if ( $jalali   !== null ) self::$jalali   = (bool) $jalali;
  72.         if ( $convert  !== null ) self::$convert  = (bool) $convert;
  73.         if ( $timezone !== null ) self::$timezone = $timezone;
  74.     }
  75.  
  76.     /**
  77.      * Convert a formatted string from Georgian Calendar to Jalali Calendar.
  78.      * This will be useful to directly convert time strings coming from databases.
  79.      * Example:
  80.      *
  81.      *  // Suppose this comes from database
  82.      *  $a = '2016-02-14 14:20:38';
  83.      *  $date = \jDateTime::convertFormatToFormat('Y-m-d H:i:s', 'Y-m-d H:i:s', $a);
  84.      *  // $date will now be '۱۳۹۴-۱۱-۲۵ ۱۴:۲۰:۳۸'
  85.      *
  86.      * @author Vahid Fazlollahzade
  87.      * @param string $jalaliFormat Return format. Same as static::date(...)
  88.      * @param string $georgianFormat The format of $timeString. See php.net/date
  89.      * @param string $timeString The time itself, formatted as $georgianFormat
  90.      * @param null|\DateTimeZone|string $timezone The timezone. Same as static::date(...)
  91.      * @return string
  92.      */
  93.     public static function convertFormatToFormat($jalaliFormat, $georgianFormat, $timeString, $timezone=null)
  94.     {
  95.         // Normalize $timezone, take from static::date(...)
  96.         $timezone = ($timezone != null) ? $timezone : ((self::$timezone != null) ? self::$timezone : date_default_timezone_get());
  97.         if (is_string($timezone)) {
  98.             $timezone = new \DateTimeZone($timezone);
  99.         } elseif (!$timezone instanceof \DateTimeZone) {
  100.             throw new \RuntimeException('Provided timezone is not correct.');
  101.         }
  102.  
  103.         // Convert to timestamp, then to Jalali
  104.         $datetime = \DateTime::createFromFormat($georgianFormat, $timeString, $timezone);
  105.         return static::date($jalaliFormat, $datetime->getTimestamp());
  106.     }
  107.  
  108.     /**
  109.      * jDateTime::Date
  110.      *
  111.      * Formats and returns given timestamp just like php's
  112.      * built in date() function.
  113.      * e.g:
  114.      * $obj->date("Y-m-d H:i", time());
  115.      * $obj->date("Y-m-d", time(), false, false, 'America/New_York');
  116.      *
  117.      * @author Sallar Kaboli
  118.      * @param $format string Acceps format string based on: php.net/date
  119.      * @param $stamp int Unix Timestamp (Epoch Time)
  120.      * @param $convert bool (Optional) forces convert action. pass null to use system default
  121.      * @param $jalali bool (Optional) forces jalali conversion. pass null to use system default
  122.      * @param $timezone string (Optional) forces a different timezone. pass null to use system default
  123.      * @return string Formatted input
  124.      */
  125.     public static function date($format, $lang, $stamp = false, $convert = null, $jalali = null, $timezone = null)
  126.     {
  127.         //Timestamp + Timezone
  128.         $stamp    = ($stamp !== false) ? $stamp : time();
  129.         $timezone = ($timezone != null) ? $timezone : ((self::$timezone != null) ? self::$timezone : date_default_timezone_get());
  130.         $obj      = new DateTime('@' . $stamp, new DateTimeZone($timezone));
  131.         $obj->setTimezone(new DateTimeZone($timezone));
  132.  
  133.         if ( (self::$jalali === false && $jalali === null) || $jalali === false ) {
  134.             return $obj->format($format);
  135.         }
  136.         else {
  137.  
  138.             //Find what to replace
  139.             $chars  = (preg_match_all('/([a-zA-Z]{1})/', $format, $chars)) ? $chars[0] : array();
  140.  
  141.             //Intact Keys
  142.             $intact = array('B','h','H','g','G','i','s','I','U','u','Z','O','P');
  143.             $intact = self::filterArray($chars, $intact);
  144.             $intactValues = array();
  145.  
  146.             foreach ($intact as $k => $v) {
  147.                 $intactValues[$k] = $obj->format($v);
  148.             }
  149.             //End Intact Keys
  150.  
  151.  
  152.  
  153.             //Changed Keys
  154.             list($year, $month, $day) = array($obj->format('Y'), $obj->format('n'), $obj->format('j'));
  155.             list($jyear, $jmonth, $jday) = self::toJalali($year, $month, $day);
  156.  
  157.             $keys   = array('d','D','j','l','N','S','w','z','W','F','m','M','n','t','L','o','Y','y','a','A','c','r','e','T');
  158.             $keys   = self::filterArray($chars, $keys, array('z'));
  159.             $values = array();
  160.  
  161.             foreach ($keys as $k => $key) {
  162.  
  163.                 $v = '';
  164.                 switch ($key) {
  165.                     //Day
  166.                     case 'd':
  167.                         $v = sprintf('%02d', $jday);
  168.                         break;
  169.                     case 'D':
  170.                         $v = self::getDayNames($obj->format('D'), true);
  171.                         break;
  172.                     case 'j':
  173.                         $v = $jday;
  174.                         break;
  175.                     case 'l':
  176.                         $v = self::getDayNames($obj->format('l'));
  177.                         break;
  178.                     case 'N':
  179.                         $v = self::getDayNames($obj->format('l'), false, 1, true);
  180.                         break;
  181.                     case 'S':
  182.                         $v = 'ام';
  183.                         break;
  184.                     case 'w':
  185.                         $v = self::getDayNames($obj->format('l'), false, 1, true) - 1;
  186.                         break;
  187.                     case 'z':
  188.                         if ($jmonth > 6) {
  189.                             $v = 186 + (($jmonth - 6 - 1) * 30) + $jday;
  190.                         }
  191.                         else {
  192.                             $v = (($jmonth - 1) * 31) + $jday;
  193.                         }
  194.                         self::$temp['z'] = $v;
  195.                         break;
  196.                     //Week
  197.                     case 'W':
  198.                         $v = is_int(self::$temp['z'] / 7) ? (self::$temp['z'] / 7) : intval(self::$temp['z'] / 7 + 1);
  199.                         break;
  200.                     //Month
  201.                     case 'F':
  202.                         $v = self::getMonthNames($jmonth,$lang);
  203.                         break;
  204.                     case 'm':
  205.                         $v = sprintf('%02d', $jmonth);
  206.                         break;
  207.                     case 'M':
  208.                         $v = self::getMonthNames($jmonth, true);
  209.                         break;
  210.                     case 'n':
  211.                         $v = $jmonth;
  212.                         break;
  213.                     case 't':
  214.                         if ($jmonth>=1 && $jmonth<=6) $v=31;
  215.                         else if ($jmonth>=7 && $jmonth<=11) $v=30;
  216.                         else if($jmonth==12 && $jyear % 4 ==3) $v=30;
  217.                         else if ($jmonth==12 && $jyear % 4 !=3) $v=29;
  218.                         break;
  219.                     //Year
  220.                     case 'L':
  221.                         $tmpObj = new DateTime('@'.(time()-31536000));
  222.                         $v = $tmpObj->format('L');
  223.                         break;
  224.                     case 'o':
  225.                     case 'Y':
  226.                         $v = $jyear;
  227.                         break;
  228.                     case 'y':
  229.                         $v = $jyear % 100;
  230.                         break;
  231.                     //Time
  232.                     case 'a':
  233.                         $v = ($obj->format('a') == 'am') ? 'ق.ظ' : 'ب.ظ';
  234.                         break;
  235.                     case 'A':
  236.                         $v = ($obj->format('A') == 'AM') ? 'قبل از ظهر' : 'بعد از ظهر';
  237.                         break;
  238.                     //Full Dates
  239.                     case 'c':
  240.                         $v  = $jyear.'-'.sprintf('%02d', $jmonth).'-'.sprintf('%02d', $jday).'T';
  241.                         $v .= $obj->format('H').':'.$obj->format('i').':'.$obj->format('s').$obj->format('P');
  242.                         break;
  243.                     case 'r':
  244.                         $v  = self::getDayNames($obj->format('D'), true).', '.sprintf('%02d', $jday).' '.self::getMonthNames($jmonth, true);
  245.                         $v .= ' '.$jyear.' '.$obj->format('H').':'.$obj->format('i').':'.$obj->format('s').' '.$obj->format('P');
  246.                         break;
  247.                     //Timezone
  248.                     case 'e':
  249.                         $v = $obj->format('e');
  250.                         break;
  251.                     case 'T':
  252.                         $v = $obj->format('T');
  253.                         break;
  254.  
  255.                 }
  256.                 $values[$k] = $v;
  257.  
  258.             }
  259.             //End Changed Keys
  260.  
  261.             //Merge
  262.             $keys   = array_merge($intact, $keys);
  263.             $values = array_merge($intactValues, $values);
  264.  
  265.             //Return
  266.             $ret = strtr($format, array_combine($keys, $values));
  267.             return
  268.                 ($convert === false ||
  269.                 ($convert === null && self::$convert === false) ||
  270.                 ( $jalali === false || $jalali === null && self::$jalali === false ))
  271.                 ? $ret : self::convertNumbers($ret);
  272.  
  273.         }
  274.  
  275.     }
  276.  
  277.     /**
  278.      * jDateTime::gDate
  279.      *
  280.      * Same as jDateTime::Date method
  281.      * but this one works as a helper and returns Gregorian Date
  282.      * in case someone doesn't like to pass all those false arguments
  283.      * to Date method.
  284.      *
  285.      * e.g. $obj->gDate("Y-m-d") //Outputs: 2011-05-05
  286.      *      $obj->date("Y-m-d", false, false, false); //Outputs: 2011-05-05
  287.      *      Both return the exact same result.
  288.      *
  289.      * @author Sallar Kaboli
  290.      * @param $format string Acceps format string based on: php.net/date
  291.      * @param $stamp int Unix Timestamp (Epoch Time)
  292.      * @param $timezone string (Optional) forces a different timezone. pass null to use system default
  293.      * @return string Formatted input
  294.      */
  295.     public static function gDate($format, $stamp = false, $timezone = null)
  296.     {
  297.         return self::date($format, $stamp, false, false, $timezone);
  298.     }
  299.  
  300.     /**
  301.      * jDateTime::Strftime
  302.      *
  303.      * Format a local time/date according to locale settings
  304.      * built in strftime() function.
  305.      * e.g:
  306.      * $obj->strftime("%x %H", time());
  307.      * $obj->strftime("%H", time(), false, false, 'America/New_York');
  308.      *
  309.      * @author Omid Pilevar
  310.      * @param $format string Acceps format string based on: php.net/date
  311.      * @param $stamp int Unix Timestamp (Epoch Time)
  312.      * @param $convert bool (Optional) forces convert action. pass null to use system default
  313.      * @param $jalali bool (Optional) forces jalali conversion. pass null to use system default
  314.      * @param $timezone string (Optional) forces a different timezone. pass null to use system default
  315.      * @return string Formatted input
  316.      */
  317.     public static function strftime($format, $stamp = false, $convert = null, $jalali = null, $timezone = null)
  318.     {
  319.         $str_format_code = array(
  320.             '%a', '%A', '%d', '%e', '%j', '%u', '%w',
  321.             '%U', '%V', '%W',
  322.             '%b', '%B', '%h', '%m',
  323.             '%C', '%g', '%G', '%y', '%Y',
  324.             '%H', '%I', '%l', '%M', '%p', '%P', '%r', '%R', '%S', '%T', '%X', '%z', '%Z',
  325.             '%c', '%D', '%F', '%s', '%x',
  326.             '%n', '%t', '%%'
  327.         );
  328.  
  329.         $date_format_code = array(
  330.             'D', 'l', 'd', 'j', 'z', 'N', 'w',
  331.             'W', 'W', 'W',
  332.             'M', 'F', 'M', 'm',
  333.             'y', 'y', 'y', 'y', 'Y',
  334.             'H', 'h', 'g', 'i', 'A', 'a', 'h:i:s A', 'H:i', 's', 'H:i:s', 'h:i:s', 'H', 'H',
  335.             'D j M H:i:s', 'd/m/y', 'Y-m-d', 'U', 'd/m/y',
  336.             '\n', '\t', '%'
  337.         );
  338.  
  339.         //Change Strftime format to Date format
  340.         $format = str_replace($str_format_code, $date_format_code, $format);
  341.  
  342.         //Convert to date
  343.         return self::date($format, $stamp, $convert, $jalali, $timezone);
  344.     }
  345.  
  346.    /**
  347.      * jDateTime::Mktime
  348.      *
  349.      * Creates a Unix Timestamp (Epoch Time) based on given parameters
  350.      * works like php's built in mktime() function.
  351.      * e.g:
  352.      * $time = $obj->mktime(0,0,0,2,10,1368);
  353.      * $obj->date("Y-m-d", $time); //Format and Display
  354.      * $obj->date("Y-m-d", $time, false, false); //Display in Gregorian !
  355.      *
  356.      * You can force gregorian mktime if system default is jalali and you
  357.      * need to create a timestamp based on gregorian date
  358.      * $time2 = $obj->mktime(0,0,0,12,23,1989, false);
  359.      *
  360.      * @author Sallar Kaboli
  361.      * @param $hour int Hour based on 24 hour system
  362.      * @param $minute int Minutes
  363.      * @param $second int Seconds
  364.      * @param $month int Month Number
  365.      * @param $day int Day Number
  366.      * @param $year int Four-digit Year number eg. 1390
  367.      * @param $jalali bool (Optional) pass false if you want to input gregorian time
  368.      * @param $timezone string (Optional) acceps an optional timezone if you want one
  369.      * @return int Unix Timestamp (Epoch Time)
  370.      */
  371.     public static function mktime($hour, $minute, $second, $month, $day, $year, $jalali = null, $timezone = null)
  372.     {
  373.         //Defaults
  374.         $month = (intval($month) == 0) ? self::date('m') : $month;
  375.         $day   = (intval($day)   == 0) ? self::date('d') : $day;
  376.         $year  = (intval($year)  == 0) ? self::date('Y') : $year;
  377.         $hour  = intval($hour);
  378.         $minute  = intval($minute);
  379.         $second  = intval($second);
  380.  
  381.         //Convert to Gregorian if necessary
  382.         if ( $jalali === true || ($jalali === null && self::$jalali === true) ) {
  383.             list($year, $month, $day) = self::toGregorian($year, $month, $day);
  384.         }
  385.  
  386.         //Create a new object and set the timezone if available
  387.         $date = $year.'-'.sprintf('%02d', $month).'-'.sprintf('%02d', $day).' '.$hour.':'.$minute.':'.$second;
  388.  
  389.         if ( self::$timezone != null || $timezone != null ) {
  390.             $obj = new DateTime($date, new DateTimeZone(($timezone != null) ? $timezone : self::$timezone));
  391.         }
  392.         else {
  393.             $obj = new DateTime($date);
  394.         }
  395.  
  396.         //Return
  397.         return $obj->format('U');
  398.     }
  399.  
  400.     /**
  401.      * jDateTime::Checkdate
  402.      *
  403.      * Checks the validity of the date formed by the arguments.
  404.      * A date is considered valid if each parameter is properly defined.
  405.      * works like php's built in checkdate() function.
  406.      * Leap years are taken into consideration.
  407.      * e.g:
  408.      * $obj->checkdate(10, 21, 1390); // Return true
  409.      * $obj->checkdate(9, 31, 1390);  // Return false
  410.      *
  411.      * You can force gregorian checkdate if system default is jalali and you
  412.      * need to check based on gregorian date
  413.      * $check = $obj->checkdate(12, 31, 2011, false);
  414.      *
  415.      * @author Omid Pilevar
  416.      * @param $month int The month is between 1 and 12 inclusive.
  417.      * @param $day int The day is within the allowed number of days for the given month.
  418.      * @param $year int The year is between 1 and 32767 inclusive.
  419.      * @param $jalali bool (Optional) pass false if you want to input gregorian time
  420.      * @return bool
  421.      */
  422.     public static function checkdate($month, $day, $year, $jalali = null)
  423.     {
  424.         //Defaults
  425.         $month = (intval($month) == 0) ? self::date('n') : intval($month);
  426.         $day   = (intval($day)   == 0) ? self::date('j') : intval($day);
  427.         $year  = (intval($year)  == 0) ? self::date('Y') : intval($year);
  428.  
  429.         //Check if its jalali date
  430.         if ( $jalali === true || ($jalali === null && self::$jalali === true) )
  431.         {
  432.             $epoch = self::mktime(0, 0, 0, $month, $day, $year);
  433.  
  434.             if( self::date('Y-n-j', $epoch,false) == "$year-$month-$day" ) {
  435.                 $ret = true;
  436.             }
  437.             else{
  438.                 $ret = false;
  439.             }
  440.         }
  441.         else //Gregorian Date
  442.         {
  443.             $ret = checkdate($month, $day, $year);
  444.         }
  445.  
  446.         //Return
  447.         return $ret;
  448.     }
  449.  
  450.     /**
  451.      * jDateTime::getdate
  452.      *
  453.      * Like php built-in function, returns an associative array containing the date information of a timestamp, or the current local time if no timestamp is given. .
  454.      *
  455.      * @author Meysam Pour Ganji
  456.      * @param $timestamp int The timestamp that whould convert to date information array, if NULL passed, current timestamp will be processed.
  457.      * @return An associative array of information related to the timestamp. For see elements of the returned associative array see {@link http://php.net/manual/en/function.getdate.php#refsect1-function.getdate-returnvalues}.
  458.      */
  459.     public static function getdate($timestamp = null)
  460.     {
  461.         if ( $timestamp === null )
  462.         {
  463.             $timestamp = time();
  464.         }
  465.  
  466.         if ( is_string($timestamp) )
  467.         {
  468.             if( ctype_digit($timestamp) || ( $timestamp{0} == '-' && ctype_digit(substr($timestamp, 1)) ) )
  469.             {
  470.                 $timestamp = (int)$timestamp;
  471.             }
  472.             else
  473.             {
  474.                 $timestamp = strtotime($timestamp);
  475.             }
  476.         }
  477.  
  478.         $dateString = self::date("s|i|G|j|w|n|Y|z|l|F", $timestamp);
  479.         $dateArray = explode("|", $dateString);
  480.  
  481.         $result = array(
  482.             "seconds" => $dateArray[0],
  483.             "minutes" => $dateArray[1],
  484.             "hours" => $dateArray[2],
  485.             "mday" => $dateArray[3],
  486.             "wday" => $dateArray[4],
  487.             "mon" => $dateArray[5],
  488.             "year" => $dateArray[6],
  489.             "yday" => $dateArray[7],
  490.             "weekday" => $dateArray[8],
  491.             "month" => $dateArray[9],
  492.             0 => $timestamp
  493.         );
  494.  
  495.         return $result;
  496.     }
  497.  
  498.     /**
  499.      * System Helpers below
  500.      * ------------------------------------------------------
  501.      */
  502.  
  503.     /**
  504.      * Filters out an array
  505.      */
  506.     private static function filterArray($needle, $heystack, $always = array())
  507.     {
  508.         return array_intersect(array_merge($needle, $always), $heystack);
  509.     }
  510.  
  511.     /**
  512.      * Returns correct names for week days
  513.      */
  514.     private static function getDayNames($day, $shorten = false, $len = 1, $numeric = false)
  515.     {
  516.         $days = array(
  517.             'sat' => array(1, 'شنبه'),
  518.             'sun' => array(2, 'یکشنبه'),
  519.             'mon' => array(3, 'دوشنبه'),
  520.             'tue' => array(4, 'سه شنبه'),
  521.             'wed' => array(5, 'چهارشنبه'),
  522.             'thu' => array(6, 'پنجشنبه'),
  523.             'fri' => array(7, 'جمعه')
  524.         );
  525.  
  526.         $day = substr(strtolower($day), 0, 3);
  527.         $day = $days[$day];
  528.  
  529.         return ($numeric) ? $day[0] : (($shorten) ? self::substr($day[1], 0, $len) : $day[1]);
  530.     }
  531.  
  532.     /**
  533.      * Returns correct names for months
  534.      */
  535.     private static function getMonthNames($month,$lang, $shorten = false, $len = 3)
  536.     {
  537.         // Convert
  538.         $months = array(
  539.             'فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'
  540.         );
  541.         if($lang=='dr') {
  542.           $months = array(
  543.               'حمل', 'ثور', 'جوزا', 'سرطان', 'اسد', 'سنبله', 'میزان', 'عقرب', 'قوس', 'جدی', 'دلو', 'حوت'
  544.           );
  545.         }
  546.         else if($lang=='pa') {
  547.           $months = array(
  548.               'وری', 'غویی', 'غبرګولی', 'چنګاښ', 'زمری', 'وږی', 'تله', 'لړم', 'لیندۍ', 'مرغومی', 'سلواغه', 'کب'
  549.           );
  550.         }
  551.  
  552.         $ret    = $months[$month - 1];
  553.  
  554.         // Return
  555.         return ($shorten) ? self::substr($ret, 0, $len) : $ret;
  556.     }
  557.  
  558.     /**
  559.      * Converts latin numbers to farsi script
  560.      */
  561.     private static function convertNumbers($matches)
  562.     {
  563.         $farsi_array   = array('۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹');
  564.         $english_array = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
  565.  
  566.         return str_replace($english_array, $farsi_array, $matches);
  567.     }
  568.  
  569.     /**
  570.      * Division
  571.      */
  572.     private static function div($a, $b)
  573.     {
  574.         return (int) ($a / $b);
  575.     }
  576.  
  577.     /**
  578.      * Substring helper
  579.      */
  580.     private static function substr($str, $start, $len)
  581.     {
  582.         if( function_exists('mb_substr') ){
  583.             return mb_substr($str, $start, $len, 'UTF-8');
  584.         }
  585.         else{
  586.             return substr($str, $start, $len * 2);
  587.         }
  588.     }
  589.  
  590.     /**
  591.      * Gregorian to Jalali Conversion
  592.      * Copyright (C) 2000  Roozbeh Pournader and Mohammad Toossi
  593.      */
  594.     public static function toJalali($g_y, $g_m, $g_d)
  595.     {
  596.  
  597.         $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  598.         $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
  599.  
  600.         $gy = $g_y-1600;
  601.         $gm = $g_m-1;
  602.         $gd = $g_d-1;
  603.  
  604.         $g_day_no = 365*$gy+self::div($gy+3, 4)-self::div($gy+99, 100)+self::div($gy+399, 400);
  605.  
  606.         for ($i=0; $i < $gm; ++$i)
  607.             $g_day_no += $g_days_in_month[$i];
  608.         if ($gm>1 && (($gy%4==0 && $gy%100!=0) || ($gy%400==0)))
  609.             $g_day_no++;
  610.         $g_day_no += $gd;
  611.  
  612.         $j_day_no = $g_day_no-79;
  613.  
  614.         $j_np = self::div($j_day_no, 12053);
  615.         $j_day_no = $j_day_no % 12053;
  616.  
  617.         $jy = 979+33*$j_np+4*self::div($j_day_no, 1461);
  618.  
  619.         $j_day_no %= 1461;
  620.  
  621.         if ($j_day_no >= 366) {
  622.             $jy += self::div($j_day_no-1, 365);
  623.             $j_day_no = ($j_day_no-1)%365;
  624.         }
  625.  
  626.         for ($i = 0; $i < 11 && $j_day_no >= $j_days_in_month[$i]; ++$i)
  627.             $j_day_no -= $j_days_in_month[$i];
  628.         $jm = $i+1;
  629.         $jd = $j_day_no+1;
  630.  
  631.         return array($jy, $jm, $jd);
  632.  
  633.     }
  634.  
  635.     /**
  636.      * Jalali to Gregorian Conversion
  637.      * Copyright (C) 2000  Roozbeh Pournader and Mohammad Toossi
  638.      *
  639.      */
  640.     public static function toGregorian($j_y, $j_m, $j_d)
  641.     {
  642.  
  643.         $g_days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  644.         $j_days_in_month = array(31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29);
  645.  
  646.         $jy = $j_y-979;
  647.         $jm = $j_m-1;
  648.         $jd = $j_d-1;
  649.  
  650.         $j_day_no = 365*$jy + self::div($jy, 33)*8 + self::div($jy%33+3, 4);
  651.         for ($i=0; $i < $jm; ++$i)
  652.             $j_day_no += $j_days_in_month[$i];
  653.  
  654.         $j_day_no += $jd;
  655.  
  656.         $g_day_no = $j_day_no+79;
  657.  
  658.         $gy = 1600 + 400*self::div($g_day_no, 146097);
  659.         $g_day_no = $g_day_no % 146097;
  660.  
  661.         $leap = true;
  662.         if ($g_day_no >= 36525) {
  663.             $g_day_no--;
  664.             $gy += 100*self::div($g_day_no,  36524);
  665.             $g_day_no = $g_day_no % 36524;
  666.  
  667.             if ($g_day_no >= 365)
  668.                 $g_day_no++;
  669.             else
  670.                 $leap = false;
  671.         }
  672.  
  673.         $gy += 4*self::div($g_day_no, 1461);
  674.         $g_day_no %= 1461;
  675.  
  676.         if ($g_day_no >= 366) {
  677.             $leap = false;
  678.  
  679.             $g_day_no--;
  680.             $gy += self::div($g_day_no, 365);
  681.             $g_day_no = $g_day_no % 365;
  682.         }
  683.  
  684.         for ($i = 0; $g_day_no >= $g_days_in_month[$i] + ($i == 1 && $leap); $i++)
  685.             $g_day_no -= $g_days_in_month[$i] + ($i == 1 && $leap);
  686.         $gm = $i+1;
  687.         $gd = $g_day_no+1;
  688.  
  689.         return array($gy, $gm, $gd);
  690.  
  691.     }
  692.  
  693. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement