class jDateTime in Persian Date for Drupal 8 8.4
Class jDateTime @package Morilog\Jalali
Hierarchy
- class \Drupal\persian_date\Library\Jalali\jDateTime
Expanded class hierarchy of jDateTime
2 files declare their use of jDateTime
- Date.php in src/
Plugin/ views/ filter/ Date.php - PersianDrupalDateTime.php in src/
Plugin/ Datetime/ PersianDrupalDateTime.php
File
- src/
Library/ Jalali/ jDateTime.php, line 11
Namespace
Drupal\persian_date\Library\JalaliView source
class jDateTime {
private static $temp;
/**
* Converts a Gregorian date to Jalali.
*
* @param $gy
* @param $gm
* @param $gd
* @return array
* 0: Year
* 1: Month
* 2: Day
*/
public static function toJalali($gy, $gm, $gd) {
return self::d2j(self::g2d($gy, $gm, $gd));
}
/**
* Converts a Jalali date to Gregorian.
*
* @param int $jy
* @param int $jm
* @param int $jd
* @return array
* 0: Year
* 1: Month
* 2: Day
*/
public static function toGregorian($jy, $jm, $jd) {
return self::d2g(self::j2d($jy, $jm, $jd));
}
/**
* Converts a Jalali date to Gregorian.
*
* @param int $jy
* @param int $jm
* @param int $jd
* @return Gregorian DateTime
*/
public static function toGregorianDate($jy, $jm, $jd) {
$georgianDateArr = self::toGregorian($jy, $jm, $jd);
$year = $georgianDateArr[0];
$month = $georgianDateArr[1];
$day = $georgianDateArr[2];
$georgianDate = new \DateTime();
$georgianDate
->setDate($year, $month, $day);
return $georgianDate;
}
/**
* Checks whether a Jalaali date is valid or not.
*
* @param int $jy
* @param int $jm
* @param int $jd
* @return bool
*/
public static function isValidateJalaliDate($jy, $jm, $jd) {
return $jy >= -61 && $jy <= 3177 && $jm >= 1 && $jm <= 12 && $jd >= 1 && $jd <= self::jalaliMonthLength($jy, $jm);
}
/**
* Checks whether a date is valid or not.
*
* @param $year
* @param $month
* @param $day
* @param bool $isJalali
* @return bool
*/
public static function checkDate($year, $month, $day, $isJalali = true) {
return $isJalali === true ? self::isValidateJalaliDate($year, $month, $day) : checkdate($month, $day, $year);
}
/**
* Is this a leap year or not?
*
* @param $jy
* @return bool
*/
public static function isLeapJalaliYear($jy) {
return self::jalaliCal($jy)['leap'] === 0;
}
/**
* Number of days in a given month in a Jalaali year.
*
* @param int $jy
* @param int $jm
* @return int
*/
public static function jalaliMonthLength($jy, $jm) {
if ($jm <= 6) {
return 31;
}
if ($jm <= 11) {
return 30;
}
return self::isLeapJalaliYear($jy) ? 30 : 29;
}
/**
* This function determines if the Jalaali (Persian) year is
* leap (366-day long) or is the common year (365 days), and
* finds the day in March (Gregorian calendar) of the first
* day of the Jalaali year (jy).
*
* @param int $jy Jalaali calendar year (-61 to 3177)
* @return array
* leap: number of years since the last leap year (0 to 4)
* gy: Gregorian year of the beginning of Jalaali year
* march: the March day of Farvardin the 1st (1st day of jy)
* @see: http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm
* @see: http://www.fourmilab.ch/documents/calendar/
*/
public static function jalaliCal($jy) {
$breaks = [
-61,
9,
38,
199,
426,
686,
756,
818,
1111,
1181,
1210,
1635,
2060,
2097,
2192,
2262,
2324,
2394,
2456,
3178,
];
$breaksCount = count($breaks);
$gy = $jy + 621;
$leapJ = -14;
$jp = $breaks[0];
if ($jy < $jp || $jy >= $breaks[$breaksCount - 1]) {
throw new \InvalidArgumentException('Invalid Jalali year : ' . $jy);
}
$jump = 0;
for ($i = 1; $i < $breaksCount; $i += 1) {
$jm = $breaks[$i];
$jump = $jm - $jp;
if ($jy < $jm) {
break;
}
$leapJ = $leapJ + self::div($jump, 33) * 8 + self::div(self::mod($jump, 33), 4);
$jp = $jm;
}
$n = $jy - $jp;
$leapJ = $leapJ + self::div($n, 33) * 8 + self::div(self::mod($n, 33) + 3, 4);
if (self::mod($jump, 33) === 4 && $jump - $n === 4) {
$leapJ += 1;
}
$leapG = self::div($gy, 4) - self::div((self::div($gy, 100) + 1) * 3, 4) - 150;
$march = 20 + $leapJ - $leapG;
if ($jump - $n < 6) {
$n = $n - $jump + self::div($jump + 4, 33) * 33;
}
$leap = self::mod(self::mod($n + 1, 33) - 1, 4);
if ($leap === -1) {
$leap = 4;
}
return [
'leap' => $leap,
'gy' => $gy,
'march' => $march,
];
}
/**
* @param $a
* @param $b
* @return float
*/
public static function div($a, $b) {
return ~~($a / $b);
}
/**
* @param $a
* @param $b
* @return mixed
*/
public static function mod($a, $b) {
return $a - ~~($a / $b) * $b;
}
/**
* @param $jdn
* @return array
*/
public static function d2g($jdn) {
$j = 4 * $jdn + 139361631;
$j += self::div(self::div(4 * $jdn + 183187720, 146097) * 3, 4) * 4 - 3908;
$i = self::div(self::mod($j, 1461), 4) * 5 + 308;
$gd = self::div(self::mod($i, 153), 5) + 1;
$gm = self::mod(self::div($i, 153), 12) + 1;
$gy = self::div($j, 1461) - 100100 + self::div(8 - $gm, 6);
return [
$gy,
$gm,
$gd,
];
}
/**
* Calculates the Julian Day number from Gregorian or Julian
* calendar dates. This integer number corresponds to the noon of
* the date (i.e. 12 hours of Universal Time).
* The procedure was tested to be good since 1 March, -100100 (of both
* calendars) up to a few million years into the future.
*
* @param int $gy Calendar year (years BC numbered 0, -1, -2, ...)
* @param int $gm Calendar month (1 to 12)
* @param int $gd Calendar day of the month (1 to 28/29/30/31)
* @return int Julian Day number
*/
public static function g2d($gy, $gm, $gd) {
return self::div(($gy + self::div($gm - 8, 6) + 100100) * 1461, 4) + self::div(153 * self::mod($gm + 9, 12) + 2, 5) + $gd - 34840408 - self::div(self::div($gy + 100100 + self::div($gm - 8, 6), 100) * 3, 4) + 752;
}
/**
* Converts a date of the Jalaali calendar to the Julian Day number.
*
* @param int $jy Jalaali year (1 to 3100)
* @param int $jm Jalaali month (1 to 12)
* @param int $jd Jalaali day (1 to 29/31)
* @return int Julian Day number
*/
public static function j2d($jy, $jm, $jd) {
$jCal = self::jalaliCal($jy);
return self::g2d($jCal['gy'], 3, $jCal['march']) + ($jm - 1) * 31 - self::div($jm, 7) * ($jm - 7) + $jd - 1;
}
/**
* Converts the Julian Day number to a date in the Jalaali calendar.
*
* @param int $jdn Julian Day number
* @return array
* 0: Jalaali year (1 to 3100)
* 1: Jalaali month (1 to 12)
* 2: Jalaali day (1 to 29/31)
*/
public static function d2j($jdn) {
$gy = self::d2g($jdn)[0];
$jy = $gy - 621;
$jCal = self::jalaliCal($jy);
$jdn1f = self::g2d($gy, 3, $jCal['march']);
$k = $jdn - $jdn1f;
if ($k >= 0) {
if ($k <= 185) {
$jm = 1 + self::div($k, 31);
$jd = self::mod($k, 31) + 1;
return [
$jy,
$jm,
$jd,
];
}
else {
$k -= 186;
}
}
else {
$jy -= 1;
$k += 179;
if ($jCal['leap'] === 1) {
$k += 1;
}
}
$jm = 7 + self::div($k, 30);
$jd = self::mod($k, 30) + 1;
return [
$jy,
$jm,
$jd,
];
}
/**
* @param $format
* @param bool $stamp
* @param bool $timezone
* @return mixed
*/
public static function date($format, $stamp = false, $timezone = null) {
$stamp = $stamp !== false ? $stamp : time();
$dateTime = static::createDateTime($stamp, $timezone);
//Find what to replace
$chars = preg_match_all('/([a-zA-Z]{1})/', $format, $chars) ? $chars[0] : array();
//Intact Keys
$intact = array(
'B',
'h',
'H',
'g',
'G',
'i',
's',
'I',
'U',
'u',
'Z',
'O',
'P',
);
$intact = self::filterArray($chars, $intact);
$intactValues = array();
foreach ($intact as $k => $v) {
$intactValues[$k] = $dateTime
->format($v);
}
//End Intact Keys
//Changed Keys
list($year, $month, $day) = array(
$dateTime
->format('Y'),
$dateTime
->format('n'),
$dateTime
->format('j'),
);
list($jYear, $jMonth, $jDay) = self::toJalali($year, $month, $day);
$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',
);
$keys = self::filterArray($chars, $keys, array(
'z',
));
$values = array();
foreach ($keys as $k => $key) {
$v = '';
switch ($key) {
//Day
case 'd':
$v = sprintf("%02d", $jDay);
break;
case 'D':
$v = self::getDayNames($dateTime
->format('D'), true);
break;
case 'j':
$v = $jDay;
break;
case 'l':
$v = self::getDayNames($dateTime
->format('l'));
break;
case 'N':
$v = self::getDayNames($dateTime
->format('l'), false, 1, true);
break;
case 'S':
$v = 'ام';
break;
case 'w':
$v = self::getDayNames($dateTime
->format('l'), false, 1, true) - 1;
break;
case 'z':
if ($jMonth > 6) {
$v = 186 + ($jMonth - 6 - 1) * 30 + $jDay;
}
else {
$v = ($jMonth - 1) * 31 + $jDay;
}
self::$temp['z'] = $v;
break;
//Week
case 'W':
$v = is_int(self::$temp['z'] / 7) ? self::$temp['z'] / 7 : intval(self::$temp['z'] / 7 + 1);
break;
//Month
case 'F':
$v = self::getMonthNames($jMonth);
break;
case 'm':
$v = sprintf("%02d", $jMonth);
break;
case 'M':
$v = self::getMonthNames($jMonth, true);
break;
case 'n':
$v = $jMonth;
break;
case 't':
$v = $jMonth == 12 ? 29 : ($jMonth > 6 && $jMonth != 12 ? 30 : 31);
break;
//Year
case 'L':
$tmpObj = static::createDateTime(time() - 31536000, $timezone);
$v = $tmpObj
->format('L');
break;
case 'o':
case 'Y':
$v = $jYear;
break;
case 'y':
$v = $jYear % 100;
break;
//Time
case 'a':
$v = $dateTime
->format('a') == 'am' ? 'ق.ظ' : 'ب.ظ';
break;
case 'A':
$v = $dateTime
->format('A') == 'AM' ? 'قبل از ظهر' : 'بعد از ظهر';
break;
//Full Dates
case 'c':
$v = $jYear . '-' . sprintf("%02d", $jMonth) . '-' . sprintf("%02d", $jDay) . 'T';
$v .= $dateTime
->format('H') . ':' . $dateTime
->format('i') . ':' . $dateTime
->format('s') . $dateTime
->format('P');
break;
case 'r':
$v = self::getDayNames($dateTime
->format('D'), true) . ', ' . sprintf("%02d", $jDay) . ' ' . self::getMonthNames($jMonth, true);
$v .= ' ' . $jYear . ' ' . $dateTime
->format('H') . ':' . $dateTime
->format('i') . ':' . $dateTime
->format('s') . ' ' . $dateTime
->format('P');
break;
//Timezone
case 'e':
$v = $dateTime
->format('e');
break;
case 'T':
$v = $dateTime
->format('T');
break;
}
$values[$k] = $v;
}
//End Changed Keys
//Merge
$keys = array_merge($intact, $keys);
$values = array_merge($intactValues, $values);
return strtr($format, array_combine($keys, $values));
}
/**
* @param $format
* @param bool $stamp
* @param null $timezone
* @return mixed
*/
public static function strftime($format, $stamp = false, $timezone = null) {
$str_format_code = array(
"%a",
"%A",
"%d",
"%e",
"%j",
"%u",
"%w",
"%U",
"%V",
"%W",
"%b",
"%B",
"%h",
"%m",
"%C",
"%g",
"%G",
"%y",
"%Y",
"%H",
"%I",
"%l",
"%M",
"%p",
"%P",
"%r",
"%R",
"%S",
"%T",
"%X",
"%z",
"%Z",
"%c",
"%D",
"%F",
"%s",
"%x",
"%n",
"%t",
"%%",
);
$date_format_code = array(
"D",
"l",
"d",
"j",
"z",
"N",
"w",
"W",
"W",
"W",
"M",
"F",
"M",
"m",
"y",
"y",
"y",
"y",
"Y",
"H",
"h",
"g",
"i",
"A",
"a",
"h:i:s A",
"H:i",
"s",
"H:i:s",
"h:i:s",
"H",
"H",
"D j M H:i:s",
"d/m/y",
"Y-m-d",
"U",
"d/m/y",
"\n",
"\t",
"%",
);
//Change Strftime format to Date format
$format = str_replace($str_format_code, $date_format_code, $format);
//Convert to date
return self::date($format, $stamp, $timezone);
}
private static function getDayNames($day, $shorten = false, $len = 1, $numeric = false) {
switch (strtolower($day)) {
case 'sat':
case 'saturday':
$ret = 'شنبه';
$n = 1;
break;
case 'sun':
case 'sunday':
$ret = 'یکشنبه';
$n = 2;
break;
case 'mon':
case 'monday':
$ret = 'دوشنبه';
$n = 3;
break;
case 'tue':
case 'tuesday':
$ret = 'سه شنبه';
$n = 4;
break;
case 'wed':
case 'wednesday':
$ret = 'چهارشنبه';
$n = 5;
break;
case 'thu':
case 'thursday':
$ret = 'پنجشنبه';
$n = 6;
break;
case 'fri':
case 'friday':
$ret = 'جمعه';
$n = 7;
break;
default:
$ret = '';
$n = -1;
}
return $numeric ? $n : ($shorten ? mb_substr($ret, 0, $len, 'UTF-8') : $ret);
}
private static function getMonthNames($month, $shorten = false, $len = 3) {
$ret = '';
switch ($month) {
case '1':
$ret = 'فروردین';
break;
case '2':
$ret = 'اردیبهشت';
break;
case '3':
$ret = 'خرداد';
break;
case '4':
$ret = 'تیر';
break;
case '5':
$ret = 'مرداد';
break;
case '6':
$ret = 'شهریور';
break;
case '7':
$ret = 'مهر';
break;
case '8':
$ret = 'آبان';
break;
case '9':
$ret = 'آذر';
break;
case '10':
$ret = 'دی';
break;
case '11':
$ret = 'بهمن';
break;
case '12':
$ret = 'اسفند';
break;
}
return $shorten ? mb_substr($ret, 0, $len, 'UTF-8') : $ret;
}
private static function filterArray($needle, $haystack, $always = array()) {
foreach ($haystack as $k => $v) {
if (!in_array($v, $needle) && !in_array($v, $always)) {
unset($haystack[$k]);
}
}
return $haystack;
}
/**
* @param $format
* @param $date
* @return array
*/
public static function parseFromFormat($format, $date) {
if ($format === 'Y-m-d') {
list($year, $month, $day) = explode('-', $date);
return [
'year' => $year,
'month' => $month,
'day' => $day,
'hour' => 12,
'minute' => 0,
'second' => 0,
];
}
// reverse engineer date formats
$keys = array(
'Y' => array(
'year',
'\\d{4}',
),
'y' => array(
'year',
'\\d{2}',
),
'm' => array(
'month',
'\\d{2}',
),
'n' => array(
'month',
'\\d{1,2}',
),
'M' => array(
'month',
'[A-Z][a-z]{3}',
),
'F' => array(
'month',
'[A-Z][a-z]{2,8}',
),
'd' => array(
'day',
'\\d{2}',
),
'j' => array(
'day',
'\\d{1,2}',
),
'D' => array(
'day',
'[A-Z][a-z]{2}',
),
'l' => array(
'day',
'[A-Z][a-z]{6,9}',
),
'u' => array(
'hour',
'\\d{1,6}',
),
'h' => array(
'hour',
'\\d{2}',
),
'H' => array(
'hour',
'\\d{2}',
),
'g' => array(
'hour',
'\\d{1,2}',
),
'G' => array(
'hour',
'\\d{1,2}',
),
'i' => array(
'minute',
'\\d{2}',
),
's' => array(
'second',
'\\d{2}',
),
);
// convert format string to regex
$regex = '';
$chars = str_split($format);
foreach ($chars as $n => $char) {
$lastChar = isset($chars[$n - 1]) ? $chars[$n - 1] : '';
$skipCurrent = '\\' == $lastChar;
if (!$skipCurrent && isset($keys[$char])) {
$regex .= '(?P<' . $keys[$char][0] . '>' . $keys[$char][1] . ')';
}
else {
if ('\\' == $char) {
$regex .= $char;
}
else {
$regex .= preg_quote($char);
}
}
}
$dt = array();
$dt['error_count'] = 0;
// now try to match it
if (preg_match('#^' . $regex . '$#', $date, $dt)) {
foreach ($dt as $k => $v) {
if (is_int($k)) {
unset($dt[$k]);
}
}
if (!jDateTime::checkdate($dt['month'], $dt['day'], $dt['year'], false)) {
$dt['error_count'] = 1;
}
}
else {
$dt['error_count'] = 1;
}
$dt['errors'] = array();
$dt['fraction'] = '';
$dt['warning_count'] = 0;
$dt['warnings'] = array();
$dt['is_localtime'] = 0;
$dt['zone_type'] = 0;
$dt['zone'] = 0;
$dt['is_dst'] = '';
if (strlen($dt['year']) == 2) {
$now = jDate::forge('now');
$x = $now
->format('Y') - $now
->format('y');
$dt['year'] += $x;
}
$dt['year'] = isset($dt['year']) ? (int) $dt['year'] : 0;
$dt['month'] = isset($dt['month']) ? (int) $dt['month'] : 0;
$dt['day'] = isset($dt['day']) ? (int) $dt['day'] : 0;
$dt['hour'] = isset($dt['hour']) ? (int) $dt['hour'] : 0;
$dt['minute'] = isset($dt['minute']) ? (int) $dt['minute'] : 0;
$dt['second'] = isset($dt['second']) ? (int) $dt['second'] : 0;
return $dt;
}
/**
* @param $format
* @param $str
* @param null $timezone
* @return \DateTime
*/
public static function createDatetimeFromFormat($format, $str, $timezone = null) {
$pd = self::parseFromFormat($format, $str);
$gd = self::toGregorian($pd['year'], $pd['month'], $pd['day']);
$date = self::createDateTime('now', $timezone);
$date
->setDate($gd[0], $gd[1], $gd[2]);
$date
->setTime($pd['hour'], $pd['minute'], $pd['second']);
return $date;
}
/**
* @param $format
* @param $str
* @param null $timezone
* @return Carbon
*/
public static function createCarbonFromFormat($format, $str, $timezone = null) {
$dateTime = self::createDatetimeFromFormat($format, $str, $timezone);
return Carbon::createFromTimestamp($dateTime
->getTimestamp(), $dateTime
->getTimezone());
}
/**
* Convert Latin numbers to persian numbers
*
* @param string $string
* @return string
*/
public static function convertNumbers($string) {
$farsi_array = array(
"۰",
"۱",
"۲",
"۳",
"۴",
"۵",
"۶",
"۷",
"۸",
"۹",
);
$english_array = array(
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
);
return str_replace($english_array, $farsi_array, $string);
}
/**
* @param $timestamp
* @param null $timezone
* @return \DateTime|static
*/
public static function createDateTime($timestamp = null, $timezone = null) {
$timezone = static::createTimeZone($timezone);
if ($timestamp === null) {
return Carbon::now($timezone);
}
if ($timestamp instanceof \DateTimeInterface) {
return $timestamp;
}
if (is_string($timestamp)) {
return new \DateTime($timestamp, $timezone);
}
if (is_numeric($timestamp)) {
return Carbon::createFromTimestamp($timestamp, $timezone);
}
throw new \InvalidArgumentException('timestamp is not valid');
}
/**
* @param null $timezone
* @return \DateTimeZone|null
*/
public static function createTimeZone($timezone = null) {
if ($timezone instanceof \DateTimeZone) {
return $timezone;
}
if ($timezone === null) {
return new \DateTimeZone(date_default_timezone_get());
}
if (is_string($timezone)) {
return new \DateTimeZone($timezone);
}
throw new \InvalidArgumentException('timezone is not valid');
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
jDateTime:: |
private static | property | ||
jDateTime:: |
public static | function | Checks whether a date is valid or not. | |
jDateTime:: |
public static | function | Convert Latin numbers to persian numbers | |
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | Converts the Julian Day number to a date in the Jalaali calendar. | |
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
private static | function | ||
jDateTime:: |
public static | function | Calculates the Julian Day number from Gregorian or Julian calendar dates. This integer number corresponds to the noon of the date (i.e. 12 hours of Universal Time). The procedure was tested to be good since 1 March, -100100 (of both calendars) up to a… | |
jDateTime:: |
private static | function | ||
jDateTime:: |
private static | function | ||
jDateTime:: |
public static | function | Is this a leap year or not? | |
jDateTime:: |
public static | function | Checks whether a Jalaali date is valid or not. | |
jDateTime:: |
public static | function | Converts a date of the Jalaali calendar to the Julian Day number. | |
jDateTime:: |
public static | function | This function determines if the Jalaali (Persian) year is leap (366-day long) or is the common year (365 days), and finds the day in March (Gregorian calendar) of the first day of the Jalaali year (jy). | |
jDateTime:: |
public static | function | Number of days in a given month in a Jalaali year. | |
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | ||
jDateTime:: |
public static | function | Converts a Jalali date to Gregorian. | |
jDateTime:: |
public static | function | Converts a Jalali date to Gregorian. | |
jDateTime:: |
public static | function | Converts a Gregorian date to Jalali. |