File: //var/www/school/wp-content/plugins/wp-parsidate/includes/parsidate.php
<?php
defined( 'ABSPATH' ) or exit( 'No direct script access allowed' );
/**
* Parsi date main conversation class
*
* Special thanks to:
* Reza Gholampanahi for convert function
*
* @author Mobin Ghasempoor
* @package WP-Parsidate
* @subpackage DateConversation
*/
class WPP_ParsiDate {
protected static $instance;
public $sessions = array( 'بهار', 'تابستان', 'پاییز', 'زمستان' );
public $persian_day_names = array( 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه' );
public $persian_day_small = array( 'ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش' );
public $j_days_in_month = array( 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 );
private $j_days_sum_month = array( 0, 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336 );
private $g_days_sum_month = array( 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 );
/**
* Constructor
*/
function __construct() {
$this->setup_vars();
}
/**
* Sets up global variables
*
* @return void
* @since 2.0
*/
private function setup_vars() {
global $wpp_months_name;
switch ( wpp_get_option( 'months_name_type' ) ) {
case 'dari':
$wpp_months_name = apply_filters( 'wpp_name_of_months', array(
'',
'حمل',
'ثور',
'جوزا',
'سرطان',
'اسد',
'سنبله',
'میزان',
'عقرب',
'قوس',
'جدی',
'دلو',
'حوت'
), 'dari' );
break;
case 'kurdish':
$wpp_months_name = apply_filters( 'wpp_name_of_months', array(
'',
'خاکەلێوە',
'گوڵان',
'جۆزەردان',
'پووشپەڕ',
'گەلاوێژ',
'خەرمانان',
'ڕەزبەر',
'گەڵاڕێزان',
'سەرماوەز',
'بەفرانبار',
'ڕێبەندان',
'ڕەشەمە'
), 'kurdish' );
break;
case 'pashto':
$wpp_months_name = apply_filters( 'wpp_name_of_months', array(
'',
'وری',
'غويی',
'غبرګولی',
'چنګاښ',
'زمری',
'وږی',
'تله',
'لړم',
'ليندۍ',
'مرغومی',
'سلواغه',
'كب'
), 'pashto' );
break;
default:
$wpp_months_name = apply_filters( 'wpp_name_of_months', array(
'',
'فروردین',
'اردیبهشت',
'خرداد',
'تیر',
'مرداد',
'شهریور',
'مهر',
'آبان',
'آذر',
'دی',
'بهمن',
'اسفند'
), 'persian' );
break;
}
}
/**
* WPP_ParsiDate::IsPerLeapYear()
* check year is leap
*
* @param mixed $year
*
* @return boolean
*/
public function IsPerLeapYear( $year ) {
$mod = $year % 33;
if ( $mod == 1 or $mod == 5 or $mod == 9 or $mod == 13 or $mod == 17 or $mod == 22 or $mod == 26 or $mod == 30 ) {
return true;
}
return false;
}
/**
* WPP_ParsiDate::IsLeapYear()
* check year is leap
*
* @param mixed $year
*
* @return boolean
*/
private function IsLeapYear( $year ) {
if ( ( ( $year % 4 ) == 0 && ( $year % 100 ) != 0 ) || ( ( $year % 400 ) == 0 ) && ( $year % 100 ) == 0 ) {
return true;
}
return false;
}
/**
* WPP_ParsiDate::persian_date()
* convert gregorian datetime to persian datetime
*
* @param mixed $format
* @param string $date
* @param string $lang
*
* @return string
*/
public function persian_date( $format, $date = 'now', $lang = 'per' ) {
global $wpp_months_name;
$j_days_in_month = array( 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 365 );
$timestamp = is_numeric( $date ) && (int) $date == $date ? $date : strtotime( $date );
$date = getdate( $timestamp );
list( $date['year'], $date['mon'], $date['mday'] ) = self::gregorian_to_persian( $date['year'], $date['mon'], $date['mday'] );
$date['mon'] = (int) $date['mon'];
$date['mday'] = (int) $date['mday'];
$out = '';
$len = strlen( $format );
for ( $i = 0; $i < $len; $i ++ ) {
switch ( $format[ $i ] ) {
//day
case'd':
$out .= ( $date['mday'] < 10 ) ? '0' . $date['mday'] : $date['mday'];
break;
case'D':
$out .= $this->persian_day_small[ $date['wday'] ];
break;
case'l':
$out .= $this->persian_day_names[ $date['wday'] ];
break;
case'j':
$out .= $date['mday'];
break;
case'N':
$out .= $this->week_day( $date['wday'] ) + 1;
break;
case'w':
$out .= $this->week_day( $date['wday'] );
break;
case'z':
if ( $date['mon'] == 12 && self::IsPerLeapYear( $date['year'] ) ) {
$out .= 30 + $date['mday'];
} else {
$out .= $this->j_days_in_month[ $date['mon'] ] + $date['mday'];
}
break;
//week
case'W':
$yday = $this->j_days_sum_month[ $date['mon'] - 1 ] + $date['mday'];
$out .= intval( $yday / 7 );
break;
//month
case'f':
$mon = $date['mon'];
switch ( $mon ) {
case( $mon < 4 ):
$out .= $this->sessions[0];
break;
case( $mon < 7 ):
$out .= $this->sessions[1];
break;
case( $mon < 10 ):
$out .= $this->sessions[2];
break;
case( $mon > 9 ):
$out .= $this->sessions[3];
break;
}
break;
case 'M':
case'F':
$out .= $wpp_months_name[ $date['mon'] ];
break;
case'm':
$out .= ( $date['mon'] < 10 ) ? '0' . $date['mon'] : $date['mon'];
break;
case'n':
$out .= $date['mon'];
break;
case'S':
$out .= 'ام';
break;
case't':
if ( $date['mon'] == 12 && self::IsPerLeapYear( $date['year'] ) ) {
$out .= 30;
} else {
$out .= $this->j_days_in_month[ $date['mon'] - 1 ];
}
break;
//year
case'L':
$out .= ( ( $date['year'] % 4 ) == 0 ) ? 1 : 0;
break;
case'o':
case'Y':
$out .= $date['year'];
break;
case'y':
$out .= substr( $date['year'], 2, 2 );
break;
//time
case'a':
$out .= ( $date['hours'] < 12 ) ? 'ق.ظ' : 'ب.ظ';
break;
case'A':
$out .= ( $date['hours'] < 12 ) ? 'قبل از ظهر' : 'بعد از ظهر';
break;
case'B':
$out .= (int) ( 1 + ( $date['mon'] / 3 ) );
break;
case'g':
$out .= ( $date['hours'] > 12 ) ? $date['hours'] - 12 : $date['hours'];
break;
case'G':
$out .= $date['hours'];
break;
case'h':
$hour = ( $date['hours'] > 12 ) ? $date['hours'] - 12 : $date['hours'];
$out .= ( $hour < 10 ) ? '0' . $hour : $hour;
break;
case'H':
$out .= ( $date['hours'] < 10 ) ? '0' . $date['hours'] : $date['hours'];
break;
case'i':
$out .= ( $date['minutes'] < 10 ) ? '0' . $date['minutes'] : $date['minutes'];
break;
case's':
$out .= ( $date['seconds'] < 10 ) ? '0' . $date['seconds'] : $date['seconds'];
break;
//full date time
case'c':
$out = $date['year'] . '/' . $date['mon'] . '/' . $date['mday'] . ' ' . $date['hours'] . ':' . ( ( $date['minutes'] < 10 ) ? '0' . $date['minutes'] : $date['minutes'] ) . ':' . ( ( $date['seconds'] < 10 ) ? '0' . $date['seconds'] : $date['seconds'] );//2004-02-12T15:19:21+00:00
break;
case'r':
$out = $this->persian_day_names[ $date['wday'] ] . ',' . $date['mday'] . ' ' . $wpp_months_name[ $date['mon'] ] . ' ' . $date['year'] . ' ' . $date['hours'] . ':' . ( ( $date['minutes'] < 10 ) ? '0' . $date['minutes'] : $date['minutes'] ) . ':' . ( ( $date['seconds'] < 10 ) ? '0' . $date['seconds'] : $date['seconds'] );//Thu, 21 Dec 2000 16:01:07
break;
case'U':
$out = $timestamp;
break;
//others
case'e':
case'I':
case'O':
case'P':
case'T':
case'Z':
case'u':
break;
default:
$out .= $format[ $i ];
}
}
if ( ! in_array( strtolower( $format ), [ 'u', 'timestamp' ] ) && $lang == 'per' ) {
return self::trim_number( $out );
} else {
return $out;
}
}
/**
* WPP_ParsiDate::gregorian_to_persian()
* convert gregorian date to persian date
*
* @param mixed $gy
* @param mixed $gm
* @param mixed $gd
*
* @return array
*/
function gregorian_to_persian( $gy, $gm, $gd ) {
$dayOfYear = $this->g_days_sum_month[ (int) $gm ] + $gd;
if ( self::IsLeapYear( $gy ) and $gm > 2 ) {
$dayOfYear ++;
}
$d_33 = (int) ( ( ( $gy - 16 ) % 132 ) * 0.0305 );
$leap = $gy % 4;
$a = ( ( $d_33 == 1 or $d_33 == 2 ) and ( $d_33 == $leap or $leap == 1 ) ) ? 78 : ( ( $d_33 == 3 and $leap == 0 ) ? 80 : 79 );
$b = ( $d_33 == 3 or $d_33 < ( $leap - 1 ) or $leap == 0 ) ? 286 : 287;
if ( (int) ( ( $gy - 10 ) / 63 ) == 30 ) {
$b --;
$a ++;
}
if ( $dayOfYear > $a ) {
$jy = $gy - 621;
$jd = $dayOfYear - $a;
} else {
$jy = $gy - 622;
$jd = $dayOfYear + $b;
}
for ( $i = 0; $i < 11 and $jd > $this->j_days_in_month[ $i ]; $i ++ ) {
$jd -= $this->j_days_in_month[ $i ];
}
$jm = ++ $i;
return array( $jy, strlen( $jm ) == 1 ? '0' . $jm : $jm, strlen( $jd ) == 1 ? '0' . $jd : $jd );
}
/**
* Get day of the week shamsi/jalali
*
* @param int $wday
*
* @return int
* @author Parsa Kafi
*
*/
private function week_day( $wday ) {
return $wday == 6 ? 0 : ++ $wday;
}
/**
* WPP_ParsiDate::trim_number()
* convert english number to persian number
*
* @param mixed $num
* @param string $sp
*
* @return string
*/
public function trim_number( $num, $sp = '٫' ) {
$eng = array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.' );
$per = array( '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', $sp );
$number = filter_var( $num, FILTER_SANITIZE_NUMBER_INT );
return empty( $number ) ? str_replace( $per, $eng, $num ) : str_replace( $eng, $per, $num );
}
/**
* WPP_ParsiDate::getInstance()
* create instance of WPP_ParsiDate class
*
* @return WPP_ParsiDate
*/
public static function getInstance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* WPP_ParsiDate::gregorian_date()
* convert persian datetime to gregorian datetime
*
* @param mixed $format
* @param mixed $persiandate
*
* @return false|string
*/
public function gregorian_date( $format, $persiandate = '' ) {
preg_match_all( '!\d+!', $persiandate, $matches );
$matches = $matches[0];
list( $year, $mon, $day ) = self::persian_to_gregorian(
$matches[0],
$matches[1],
$matches[2]
);
return date(
$format,
mktime(
isset( $matches[3] ) ? $matches[3] : 0,
isset( $matches[4] ) ? $matches[4] : 0,
isset( $matches[5] ) ? $matches[5] : 0,
$mon,
$day,
$year
)
);
}
/**
* WPP_ParsiDate::persian_to_gregorian()
* convert persian date to gregorian date
*
* @param mixed $jy
* @param mixed $jm
* @param mixed $jd
*
* @return array
*/
public function persian_to_gregorian( $jy, $jm, $jd ) {
$doyj = ( $jm - 2 > - 1 ? $this->j_days_sum_month[ (int) $jm ] + $jd : $jd );
$d4 = ( $jy + 1 ) % 4;
$d33 = (int) ( ( ( $jy - 55 ) % 132 ) * .0305 );
$a = ( $d33 != 3 and $d4 <= $d33 ) ? 287 : 286;
$b = ( ( $d33 == 1 or $d33 == 2 ) and ( $d33 == $d4 or $d4 == 1 ) ) ? 78 : ( ( $d33 == 3 and $d4 == 0 ) ? 80 : 79 );
if ( (int) ( ( $jy - 19 ) / 63 ) == 20 ) {
$a --;
$b ++;
}
if ( $doyj <= $a ) {
$gy = $jy + 621;
$gd = $doyj + $b;
} else {
$gy = $jy + 622;
$gd = $doyj - $a;
}
foreach ( array( 0, 31, ( $gy % 4 == 0 ) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ) as $gm => $days ) {
if ( $gd <= $days ) {
break;
}
$gd -= $days;
}
return array( $gy, $gm, $gd );
}
}
/**
* convert gregorian datetime to persian datetime
*
* @param mixed $input
* @param string $datetime
* @param string $lang
*
* @return string
*/
function parsidate( $input, $datetime = 'now', $lang = 'per' ) {
$bndate = WPP_ParsiDate::getInstance();
return $bndate->persian_date( $input, $datetime, $lang );
}
/**
* gregdate()
* convert persian datetime to gregorian datetime
*
* @param mixed $input
* @param mixed $datetime
*
* @return false|string
*/
function gregdate( $input, $datetime ) {
$bndate = WPP_ParsiDate::getInstance();
return $bndate->gregorian_date( $input, $datetime );
}