PluginProbe ʕ •ᴥ•ʔ
پارسی دیت – Parsi Date / 6.2.1
پارسی دیت – Parsi Date v6.2.1
6.2.1 6.2 6.1 5.1.6 5.1.7 5.1.8 5.1.8.2 6.0 trunk 1.0 1.1 1.2 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 2.0.0-alpha 2.1 2.1.1 2.1.2 2.1.3 2.1.5 2.1.6 2.1.7 2.2.0 2.2.1 2.2.2 2.2.3 2.3.0.1 2.3.0.2 2.3.1 2.3.2 2.3.3 2.3.4 3.0.1 3.0.2 3.0.3 4.0.0 4.0.1 4.0.2 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5
wp-parsidate / inc / Core / WPP_ParsiDate.php
wp-parsidate / inc / Core Last commit date
Archive.php 2 weeks ago Calendar.php 2 weeks ago Core.php 2 weeks ago Names.php 2 weeks ago Posts.php 2 weeks ago WPP_ParsiDate.php 2 weeks ago
WPP_ParsiDate.php
406 lines
1 <?php
2
3 namespace WPParsidate\Core;
4
5 defined( 'ABSPATH' ) or exit( 'No direct script access allowed' );
6
7 /**
8 * Parsi date main conversation class
9 *
10 * Special thanks to:
11 * Reza Gholampanahi for convert function
12 *
13 * @author Mobin Ghasempoor
14 * @package WP-Parsidate
15 * @subpackage DateConversation
16 */
17 class WPP_ParsiDate {
18 protected static $instance;
19
20 public array $sessions = array( 'بهار', 'تابستان', 'پاییز', 'ز�
21 ستان' );
22
23 public array $persian_day_names = array( 'یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'ج�
24 عه', 'شنبه' );
25 public array $persian_day_small = array( 'ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش' );
26
27 public array $j_days_in_month = array( 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 );
28 private array $j_days_sum_month = array( 0, 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336 );
29 private array $g_days_sum_month = array( 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 );
30
31 /**
32 * Check year is leaped
33 *
34 * @param mixed $year
35 *
36 * @return boolean
37 */
38 public function IsPerLeapYear( $year ): bool {
39 $mod = $year % 33;
40
41 return $mod === 1 || $mod === 5 || $mod === 9 || $mod === 13 || $mod === 17 || $mod === 22 || $mod === 26 || $mod === 30;
42 }
43
44 /**
45 * WPP_ParsiDate::IsLeapYear()
46 * check year is leap
47 *
48 * @param mixed $year
49 *
50 * @return boolean
51 */
52 private function IsLeapYear( $year ): bool {
53 return ( ( $year % 4 ) === 0 && ( $year % 100 ) !== 0 ) || ( ( ( $year % 400 ) === 0 ) && ( $year % 100 ) === 0 );
54 }
55
56 /**
57 * WPP_ParsiDate::persian_date()
58 * convert gregorian datetime to persian datetime
59 *
60 * @param mixed $format
61 * @param string $date
62 * @param string $lang
63 *
64 * @return string
65 */
66 public function persian_date( $format, $date = 'now', $lang = 'per' ) {
67 $months_name = Names::getMonths();
68 $day_names = Names::getWeekDays();
69 //$j_days_in_month = array( 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 365 );
70 $timestamp = is_numeric( $date ) && (int) $date == $date ? $date : ( $date ? strtotime( $date ) : time() );
71 $date = getdate( $timestamp );
72
73 list( $date['year'], $date['mon'], $date['mday'] ) = $this->gregorian_to_persian( $date['year'], $date['mon'],
74 $date['mday'] );
75
76 $date['mon'] = (int) $date['mon'];
77 $date['mday'] = (int) $date['mday'];
78 $out = '';
79 $len = strlen( $format );
80
81 for ( $i = 0; $i < $len; $i ++ ) {
82 switch ( $format[ $i ] ) {
83 //day
84 case'd':
85 $out .= ( $date['mday'] < 10 ) ? '0' . $date['mday'] : $date['mday'];
86 break;
87 case'D':
88 $out .= $this->persian_day_small[ $date['wday'] ];
89 break;
90 case'l':
91 $out .= $day_names[ $date['wday'] ];
92 break;
93 case'j':
94 $out .= $date['mday'];
95 break;
96 case'N':
97 $out .= $this->week_day( $date['wday'] ) + 1;
98 break;
99 case'w':
100 $out .= $this->week_day( $date['wday'] );
101 break;
102 case'z':
103 if ( $date['mon'] === 12 && $this->IsPerLeapYear( $date['year'] ) ) {
104 $out .= 30 + $date['mday'];
105 } else {
106 $out .= $this->j_days_in_month[ $date['mon'] ] + $date['mday'];
107 }
108 break;
109 //week
110 case'W':
111 $yday = $this->j_days_sum_month[ $date['mon'] - 1 ] + $date['mday'];
112 $out .= (int) ( $yday / 7 );
113 break;
114 //month
115 case'f':
116 $mon = $date['mon'];
117 switch ( $mon ) {
118 case( $mon < 4 ):
119 $out .= $this->sessions[0];
120 break;
121 case( $mon < 7 ):
122 $out .= $this->sessions[1];
123 break;
124 case( $mon < 10 ):
125 $out .= $this->sessions[2];
126 break;
127 case( $mon > 9 ):
128 $out .= $this->sessions[3];
129 break;
130 }
131 break;
132 case 'M':
133 case'F':
134 $out .= $months_name[ $date['mon'] ];
135 break;
136 case'm':
137 $out .= ( $date['mon'] < 10 ) ? '0' . $date['mon'] : $date['mon'];
138 break;
139 case'n':
140 $out .= $date['mon'];
141 break;
142 case'S':
143 $out .= 'ا�
144 ';
145 break;
146 case't':
147 if ( $date['mon'] === 12 && $this->IsPerLeapYear( $date['year'] ) ) {
148 $out .= 30;
149 } else {
150 $out .= $this->j_days_in_month[ $date['mon'] - 1 ];
151 }
152 break;
153 //year
154 case'L':
155 $out .= ( ( $date['year'] % 4 ) === 0 ) ? 1 : 0;
156 break;
157 case'o':
158 case'Y':
159 $out .= $date['year'];
160 break;
161 case'y':
162 $out .= substr( $date['year'], 2, 2 );
163 break;
164 //time
165 case'a':
166 $out .= ( $date['hours'] < 12 ) ? 'ق.ظ' : 'ب.ظ';
167 break;
168 case'A':
169 $out .= ( $date['hours'] < 12 ) ? 'قبل از ظهر' : 'بعد از ظهر';
170 break;
171 case'B':
172 $out .= (int) ( 1 + ( $date['mon'] / 3 ) );
173 break;
174 case'g':
175 $out .= ( $date['hours'] > 12 ) ? $date['hours'] - 12 : $date['hours'];
176 break;
177 case'G':
178 $out .= $date['hours'];
179 break;
180 case'h':
181 $hour = ( $date['hours'] > 12 ) ? $date['hours'] - 12 : $date['hours'];
182 $out .= ( $hour < 10 ) ? '0' . $hour : $hour;
183 break;
184 case'H':
185 $out .= ( $date['hours'] < 10 ) ? '0' . $date['hours'] : $date['hours'];
186 break;
187 case'i':
188 $out .= ( $date['minutes'] < 10 ) ? '0' . $date['minutes'] : $date['minutes'];
189 break;
190 case's':
191 $out .= ( $date['seconds'] < 10 ) ? '0' . $date['seconds'] : $date['seconds'];
192 break;
193 //full date time
194 case'c':
195 $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
196 break;
197 case'r':
198 $out = $day_names[ $date['wday'] ] . ',' . $date['mday'] . ' ' . $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
199 break;
200 case'U':
201 $out = $timestamp;
202 break;
203 //others
204 case'e':
205 case'I':
206 case'O':
207 case'P':
208 case'T':
209 case'Z':
210 case'u':
211 break;
212 default:
213 $out .= $format[ $i ];
214 }
215 }
216
217 if ( $lang === 'per' && ! in_array( strtolower( $format ), [ 'u', 'timestamp' ] ) ) {
218 return $this->trim_number( $out );
219 } else {
220 return $out;
221 }
222 }
223
224 /**
225 * WPP_ParsiDate::gregorian_to_persian()
226 * convert gregorian date to persian date
227 *
228 * @param mixed $gy
229 * @param mixed $gm
230 * @param mixed $gd
231 *
232 * @return array
233 */
234 public function gregorian_to_persian( $gy, $gm, $gd ): array {
235 $dayOfYear = $this->g_days_sum_month[ (int) $gm ] + $gd;
236
237 if ( $this->IsLeapYear( $gy ) and $gm > 2 ) {
238 $dayOfYear ++;
239 }
240
241 $d_33 = (int) ( ( ( $gy - 16 ) % 132 ) * 0.0305 );
242 $leap = $gy % 4;
243 $a = ( ( $d_33 === 1 or $d_33 === 2 ) and ( $d_33 === $leap or $leap === 1 ) ) ? 78 : ( ( $d_33 === 3 and $leap === 0 ) ? 80 : 79 );
244 $b = ( $d_33 === 3 or $d_33 < ( $leap - 1 ) or $leap === 0 ) ? 286 : 287;
245
246 if ( (int) ( ( $gy - 10 ) / 63 ) === 30 ) {
247 $b --;
248 $a ++;
249 }
250
251 if ( $dayOfYear > $a ) {
252 $jy = $gy - 621;
253 $jd = $dayOfYear - $a;
254 } else {
255 $jy = $gy - 622;
256 $jd = $dayOfYear + $b;
257 }
258
259 for ( $i = 0; $i < 11 and $jd > $this->j_days_in_month[ $i ]; $i ++ ) {
260 $jd -= $this->j_days_in_month[ $i ];
261 }
262
263 $jm = ++ $i;
264
265 return array( $jy, strlen( $jm ) === 1 ? '0' . $jm : $jm, strlen( $jd ) === 1 ? '0' . $jd : $jd );
266 }
267
268 /**
269 * Get day of the week shamsi/jalali
270 *
271 * @param int $wday
272 *
273 * @return int
274 * @author Parsa Kafi
275 *
276 */
277 private function week_day( $wday ) {
278 return $wday === 6 ? 0 : ++ $wday;
279 }
280
281 /**
282 * WPP_ParsiDate::trim_number()
283 * convert english number to persian number
284 *
285 * @param mixed $num
286 * @param string $sp
287 *
288 * @return string
289 */
290 public function trim_number( $num, $sp = '٫' ): string {
291 $eng = array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.' );
292 $per = array( '۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', $sp );
293 $number = filter_var( $num, FILTER_SANITIZE_NUMBER_INT );
294
295 return empty( $number ) ? str_replace( $per, $eng, $num ) : str_replace( $eng, $per, $num );
296 }
297
298 /**
299 * WPP_ParsiDate::getInstance()
300 * create instance of WPP_ParsiDate class
301 *
302 * @return WPP_ParsiDate
303 */
304 public static function getInstance(): WPP_ParsiDate {
305 if ( ! isset( self::$instance ) ) {
306 self::$instance = new self();
307 }
308
309 return self::$instance;
310 }
311
312 /**
313 * WPP_ParsiDate::gregorian_date()
314 * convert persian datetime to gregorian datetime
315 *
316 * @param mixed $format
317 * @param mixed $persianDate
318 *
319 * @return false|string
320 */
321 public function gregorian_date( $format, $persianDate = '' ) {
322 preg_match_all( '!\d+!', $persianDate, $matches );
323
324 $matches = $matches[0];
325
326 if ( count( $matches ) < 3 ) {
327 return $persianDate;
328 }
329
330 [ $year, $mon, $day ] = $this->persian_to_gregorian(
331 $matches[0],
332 $matches[1],
333 $matches[2]
334 );
335
336 return date(
337 $format,
338 mktime(
339 $matches[3] ?? 0,
340 $matches[4] ?? 0,
341 $matches[5] ?? 0,
342 $mon,
343 $day,
344 $year
345 )
346 );
347 }
348
349 /**
350 * WPP_ParsiDate::persian_to_gregorian()
351 * convert persian date to gregorian date
352 *
353 * @param mixed $jy
354 * @param mixed $jm
355 * @param mixed $jd
356 *
357 * @return array
358 */
359 public function persian_to_gregorian( $jy, $jm, $jd ) {
360 $doyj = ( $jm - 2 > - 1 ? $this->j_days_sum_month[ (int) $jm ] + $jd : $jd );
361 $d4 = ( $jy + 1 ) % 4;
362 $d33 = (int) ( ( ( $jy - 55 ) % 132 ) * .0305 );
363 $a = ( $d33 !== 3 and $d4 <= $d33 ) ? 287 : 286;
364 $b = ( ( $d33 === 1 or $d33 === 2 ) and ( $d33 === $d4 or $d4 === 1 ) ) ? 78 : ( ( $d33 === 3 and $d4 === 0 ) ? 80 : 79 );
365
366 if ( (int) ( ( $jy - 19 ) / 63 ) === 20 ) {
367 $a --;
368 $b ++;
369 }
370
371 if ( $doyj <= $a ) {
372 $gy = $jy + 621;
373 $gd = $doyj + $b;
374 } else {
375 $gy = $jy + 622;
376 $gd = $doyj - $a;
377 }
378
379 foreach (
380 array(
381 0,
382 31,
383 ( $gy % 4 === 0 ) ? 29 : 28,
384 31,
385 30,
386 31,
387 30,
388 31,
389 31,
390 30,
391 31,
392 30,
393 31
394 ) as $gm => $days
395 ) {
396 if ( $gd <= $days ) {
397 break;
398 }
399
400 $gd -= $days;
401 }
402
403 return array( $gy, $gm, $gd );
404 }
405 }
406