Issues (236)

src/external/jdf.php (7 issues)

1
<?php
2
3
namespace BPT\external;
4
5
/**
6
 * Time and date class for persian calendar(Solar calendar, Shamsi calendar)
7
 *
8
 * @Author : Reza Gholampanahi & WebSite : http://jdf.scr.ir
9
 * @License: GNU/LGPL _ Open Source & Free : [all functions]
10
 * @Version: 2.76 =>[ 1399/11/28 = 1442/07/04 = 2021/02/16 ]
11
 */
12
class jdf {
13
    public static function jdate ($format, $timestamp = '', $none = '', $time_zone = 'Asia/Tehran', $tr_num = 'fa') {
0 ignored issues
show
The parameter $none is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

13
    public static function jdate ($format, $timestamp = '', /** @scrutinizer ignore-unused */ $none = '', $time_zone = 'Asia/Tehran', $tr_num = 'fa') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
14
        $T_sec = 0;
15
        if ($time_zone != 'local') {
16
            date_default_timezone_set(empty($time_zone) ? 'Asia/Tehran' : $time_zone);
17
        }
18
        $timestamp = $T_sec + empty($timestamp) ? time() : self::tr_num($timestamp);
19
        $date = explode('_', date('H_i_j_n_O_P_s_w_Y', $timestamp));
20
        [$jalali_year, $jalali_month, $jalali_day] = self::gregorian_to_jalali($date[8], $date[3], $date[2]);
21
        $doy = $jalali_month < 7 ? ($jalali_month - 1) * 31 + $jalali_day - 1 : ($jalali_month - 7) * 30 + $jalali_day + 185;
22
        $leap_year = ($jalali_year + 12) % 33 % 4 == 1 ? 1 : 0;
23
        $length = strlen($format);
24
        $output = '';
25
        for ($i = 0; $i < $length; $i++) {
26
            $sub = substr($format, $i, 1);
27
            if ($sub == '\\') {
28
                $output .= substr($format, ++$i, 1);
29
                continue;
30
            }
31
            switch ($sub) {
32
                case 'E':
33
                case 'R':
34
                case 'x':
35
                case 'X':
36
                    $output .= 'http://jdf.scr.ir';
37
                    break;
38
                case 'B':
39
                case 'e':
40
                case 'g':
41
                case 'G':
42
                case 'h':
43
                case 'I':
44
                case 'T':
45
                case 'u':
46
                case 'Z':
47
                    $output .= date($sub, $timestamp);
48
                    break;
49
                case 'a':
50
                    $output .= $date[0] < 12 ? 'ق.ظ' : 'ب.ظ';
51
                    break;
52
                case 'A':
53
                    $output .= $date[0] < 12 ? 'قبل از ظهر' : 'بعد از ظهر';
54
                    break;
55
                case 'b':
56
                    $output .= (int) ($jalali_month / 3.1) + 1;
57
                    break;
58
                case 'c':
59
                    $output .= $jalali_year . '/' . $jalali_month . '/' . $jalali_day . ' ،' . $date[0] . ':' . $date[1] . ':' . $date[6] . ' ' . $date[5];
60
                    break;
61
                case 'C':
62
                    $output .= (int) (($jalali_year + 99) / 100);
63
                    break;
64
                case 'd':
65
                    $output .= $jalali_day < 10 ? '0' . $jalali_day : $jalali_day;
66
                    break;
67
                case 'D':
68
                    $output .= self::jdate_words(['kh' => $date[7]], ' ');
69
                    break;
70
                case 'f':
71
                    $output .= self::jdate_words(['ff' => $jalali_month], ' ');
72
                    break;
73
                case 'F':
74
                    $output .= self::jdate_words(['mm' => $jalali_month], ' ');
75
                    break;
76
                case 'H':
77
                    $output .= $date[0];
78
                    break;
79
                case 'i':
80
                    $output .= $date[1];
81
                    break;
82
                case 'j':
83
                    $output .= $jalali_day;
84
                    break;
85
                case 'J':
86
                    $output .= self::jdate_words(['rr' => $jalali_day], ' ');
87
                    break;
88
                case 'k';
89
                    $output .= self::tr_num(100 - (int) ($doy / ($leap_year + 365.24) * 1000) / 10, $tr_num);
90
                    break;
91
                case 'K':
92
                    $output .= self::tr_num((int) ($doy / ($leap_year + 365.24) * 1000) / 10, $tr_num);
93
                    break;
94
                case 'l':
95
                    $output .= self::jdate_words(['rh' => $date[7]], ' ');
96
                    break;
97
                case 'L':
98
                    $output .= $leap_year;
99
                    break;
100
                case 'm':
101
                    $output .= $jalali_month > 9 ? $jalali_month : '0' . $jalali_month;
102
                    break;
103
                case 'M':
104
                    $output .= self::jdate_words(['km' => $jalali_month], ' ');
105
                    break;
106
                case 'n':
107
                    $output .= $jalali_month;
108
                    break;
109
                case 'N':
110
                    $output .= $date[7] + 1;
111
                    break;
112
                case 'o':
113
                    $jdw = $date[7] == 6 ? 0 : $date[7] + 1;
114
                    $dny = 364 + $leap_year - $doy;
115
                    $output .= ($jdw > $doy + 3 and $doy < 3) ? $jalali_year - 1 : ((3 - $dny > $jdw and $dny < 3) ? $jalali_year + 1 : $jalali_year);
116
                    break;
117
                case 'O':
118
                    $output .= $date[4];
119
                    break;
120
                case 'p':
121
                    $output .= self::jdate_words(['mb' => $jalali_month], ' ');
122
                    break;
123
                case 'P':
124
                    $output .= $date[5];
125
                    break;
126
                case 'q':
127
                    $output .= self::jdate_words(['sh' => $jalali_year], ' ');
128
                    break;
129
                case 'Q':
130
                    $output .= $leap_year + 364 - $doy;
131
                    break;
132
                case 'r':
133
                    $key = self::jdate_words(['rh' => $date[7], 'mm' => $jalali_month]);
134
                    $output .= $date[0] . ':' . $date[1] . ':' . $date[6] . ' ' . $date[4] . ' ' . $key['rh'] . '، ' . $jalali_day . ' ' . $key['mm'] . ' ' . $jalali_year;
135
                    break;
136
                case 's':
137
                    $output .= $date[6];
138
                    break;
139
                case 'S':
140
                    $output .= 'ام';
141
                    break;
142
                case 't':
143
                    $output .= $jalali_month != 12 ? 31 - (int) ($jalali_month / 6.5) : ($leap_year + 29);
144
                    break;
145
                case 'U':
146
                    $output .= $timestamp;
147
                    break;
148
                case 'v':
149
                    $output .= self::jdate_words(['ss' => ($jalali_year % 100)], ' ');
150
                    break;
151
                case 'V':
152
                    $output .= self::jdate_words(['ss' => $jalali_year], ' ');
153
                    break;
154
                case 'w':
155
                    $output .= $date[7] == 6 ? 0 : $date[7] + 1;
156
                    break;
157
                case 'W':
158
                    $avs = ($date[7] == 6 ? 0 : $date[7] + 1) - $doy % 7;
159
                    if ($avs < 0) $avs += 7;
160
                    $num = (int) (($doy + $avs) / 7);
161
                    if ($avs < 4) {
162
                        $num++;
163
                    }
164
                    elseif ($num < 1) {
165
                        $num = ($avs == 4 or $avs == ($jalali_year % 33 % 4 - 2 == (int) ($jalali_year % 33 * 0.05) ? 5 : 4)) ? 53 : 52;
166
                    }
167
                    $aks = $avs + $leap_year;
168
                    if ($aks == 7) {
169
                        $aks = 0;
170
                    }
171
                    $output .= ($leap_year + 363 - $doy < $aks and $aks < 3) ? '01' : ($num < 10 ? '0' . $num : $num);
172
                    break;
173
                case 'y':
174
                    $output .= substr($jalali_year, 2, 2);
175
                    break;
176
                case 'Y':
177
                    $output .= $jalali_year;
178
                    break;
179
                case 'z':
180
                    $output .= $doy;
181
                    break;
182
                default:
183
                    $output .= $sub;
184
            }
185
        }
186
        return $tr_num != 'en' ? self::tr_num($output, 'fa', '.') : $output;
187
    }
188
    public static function jstrftime ($format, $timestamp = '', $none = '', $time_zone = 'Asia/Tehran', $tr_num = 'fa') {
0 ignored issues
show
The parameter $none is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

188
    public static function jstrftime ($format, $timestamp = '', /** @scrutinizer ignore-unused */ $none = '', $time_zone = 'Asia/Tehran', $tr_num = 'fa') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
189
        $T_sec = 0;/* <= رفع خطاي زمان سرور ، با اعداد '+' و '-' بر حسب ثانيه */
190
        if ($time_zone != 'local') date_default_timezone_set(($time_zone === '') ? 'Asia/Tehran' : $time_zone);
191
        $timestamp = $T_sec + (($timestamp === '') ? time() : self::tr_num($timestamp));
192
        $date = explode('_', date('h_H_i_j_n_s_w_Y', $timestamp));
193
        [$jalali_year, $jalali_month, $jalali_day] = self::gregorian_to_jalali($date[7], $date[4], $date[3]);
194
        $doy = ($jalali_month < 7) ? (($jalali_month - 1) * 31) + $jalali_day - 1 : (($jalali_month - 7) * 30) + $jalali_day + 185;
195
        $leap_year = (((($jalali_year + 12) % 33) % 4) == 1) ? 1 : 0;
196
        $length = strlen($format);
197
        $output = '';
198
        for ($i = 0; $i < $length; $i++) {
199
            $sub = substr($format, $i, 1);
200
            if ($sub == '%') {
201
                $sub = substr($format, ++$i, 1);
202
            }
203
            else {
204
                $output .= $sub;
205
                continue;
206
            }
207
            switch ($sub) {
208
209
                /* Day */ case 'a':
210
                $output .= self::jdate_words(['kh' => $date[6]], ' ');
211
                break;
212
                case 'A':
213
                    $output .= self::jdate_words(['rh' => $date[6]], ' ');
214
                    break;
215
                case 'd':
216
                    $output .= ($jalali_day < 10) ? '0' . $jalali_day : $jalali_day;
217
                    break;
218
                case 'e':
219
                    $output .= ($jalali_day < 10) ? ' ' . $jalali_day : $jalali_day;
220
                    break;
221
                case 'j':
222
                    $output .= str_pad($doy + 1, 3, 0, STR_PAD_LEFT);
223
                    break;
224
                case 'u':
225
                    $output .= $date[6] + 1;
226
                    break;
227
                case 'w':
228
                    $output .= ($date[6] == 6) ? 0 : $date[6] + 1;
229
                    break;
230
                /* Week */ case 'U':
231
                $avs = (($date[6] < 5) ? $date[6] + 2 : $date[6] - 5) - ($doy % 7);
232
                if ($avs < 0) $avs += 7;
233
                $num = (int) (($doy + $avs) / 7) + 1;
234
                if ($avs > 3 or $avs == 1) $num--;
235
                $output .= ($num < 10) ? '0' . $num : $num;
236
                break;
237
                case 'V':
238
                    $avs = (($date[6] == 6) ? 0 : $date[6] + 1) - ($doy % 7);
239
                    if ($avs < 0) $avs += 7;
240
                    $num = (int) (($doy + $avs) / 7);
241
                    if ($avs < 4) {
242
                        $num++;
243
                    }
244
                    elseif ($num < 1) {
245
                        $num = ($avs == 4 or $avs == ((((($jalali_year % 33) % 4) - 2) == ((int) (($jalali_year % 33) * 0.05))) ? 5 : 4)) ? 53 : 52;
246
                    }
247
                    $aks = $avs + $leap_year;
248
                    if ($aks == 7) $aks = 0;
249
                    $output .= (($leap_year + 363 - $doy) < $aks and $aks < 3) ? '01' : (($num < 10) ? '0' . $num : $num);
250
                    break;
251
                case 'W':
252
                    $avs = (($date[6] == 6) ? 0 : $date[6] + 1) - ($doy % 7);
253
                    if ($avs < 0) $avs += 7;
254
                    $num = (int) (($doy + $avs) / 7) + 1;
255
                    if ($avs > 3) $num--;
256
                    $output .= ($num < 10) ? '0' . $num : $num;
257
                    break;
258
                /* Month */ case 'b':
259
                case 'h':
260
                    $output .= self::jdate_words(['km' => $jalali_month], ' ');
261
                    break;
262
                case 'B':
263
                    $output .= self::jdate_words(['mm' => $jalali_month], ' ');
264
                    break;
265
                case 'm':
266
                    $output .= ($jalali_month > 9) ? $jalali_month : '0' . $jalali_month;
267
                    break;
268
                /* Year */ case 'C':
269
                $tmp = (int) ($jalali_year / 100);
270
                $output .= ($tmp > 9) ? $tmp : '0' . $tmp;
271
                break;
272
                case 'g':
273
                    $jdw = ($date[6] == 6) ? 0 : $date[6] + 1;
274
                    $dny = 364 + $leap_year - $doy;
275
                    $output .= substr(($jdw > ($doy + 3) and $doy < 3) ? $jalali_year - 1 : (((3 - $dny) > $jdw and $dny < 3) ? $jalali_year + 1 : $jalali_year), 2, 2);
276
                    break;
277
                case 'G':
278
                    $jdw = ($date[6] == 6) ? 0 : $date[6] + 1;
279
                    $dny = 364 + $leap_year - $doy;
280
                    $output .= ($jdw > ($doy + 3) and $doy < 3) ? $jalali_year - 1 : (((3 - $dny) > $jdw and $dny < 3) ? $jalali_year + 1 : $jalali_year);
281
                    break;
282
                case 'y':
283
                    $output .= substr($jalali_year, 2, 2);
284
                    break;
285
                case 'Y':
286
                    $output .= $jalali_year;
287
                    break;
288
                /* Time */ case 'H':
289
                $output .= $date[1];
290
                break;
291
                case 'I':
292
                    $output .= $date[0];
293
                    break;
294
                case 'l':
295
                    $output .= ($date[0] > 9) ? $date[0] : ' ' . (int) $date[0];
296
                    break;
297
                case 'M':
298
                    $output .= $date[2];
299
                    break;
300
                case 'p':
301
                    $output .= ($date[1] < 12) ? 'قبل از ظهر' : 'بعد از ظهر';
302
                    break;
303
                case 'P':
304
                    $output .= ($date[1] < 12) ? 'ق.ظ' : 'ب.ظ';
305
                    break;
306
                case 'r':
307
                    $output .= $date[0] . ':' . $date[2] . ':' . $date[5] . ' ' . (($date[1] < 12) ? 'قبل از ظهر' : 'بعد از ظهر');
308
                    break;
309
                case 'R':
310
                    $output .= $date[1] . ':' . $date[2];
311
                    break;
312
                case 'S':
313
                    $output .= $date[5];
314
                    break;
315
                case 'T':
316
                    $output .= $date[1] . ':' . $date[2] . ':' . $date[5];
317
                    break;
318
                case 'X':
319
                    $output .= $date[0] . ':' . $date[2] . ':' . $date[5];
320
                    break;
321
                case 'z':
322
                    $output .= date('O', $timestamp);
323
                    break;
324
                case 'Z':
325
                    $output .= date('T', $timestamp);
326
                    break;
327
                /* Time and Date Stamps */ case 'c':
328
                $key = self::jdate_words(['rh' => $date[6], 'mm' => $jalali_month]);
329
                $output .= $date[1] . ':' . $date[2] . ':' . $date[5] . ' ' . date('P', $timestamp) . ' ' . $key['rh'] . '، ' . $jalali_day . ' ' . $key['mm'] . ' ' . $jalali_year;
330
                break;
331
                case 'D':
332
                    $output .= substr($jalali_year, 2, 2) . '/' . (($jalali_month > 9) ? $jalali_month : '0' . $jalali_month) . '/' . (($jalali_day < 10) ? '0' . $jalali_day : $jalali_day);
333
                    break;
334
                case 'F':
335
                    $output .= $jalali_year . '-' . (($jalali_month > 9) ? $jalali_month : '0' . $jalali_month) . '-' . (($jalali_day < 10) ? '0' . $jalali_day : $jalali_day);
336
                    break;
337
                case 's':
338
                    $output .= $timestamp;
339
                    break;
340
                case 'x':
341
                    $output .= substr($jalali_year, 2, 2) . '/' . (($jalali_month > 9) ? $jalali_month : '0' . $jalali_month) . '/' . (($jalali_day < 10) ? '0' . $jalali_day : $jalali_day);
342
                    break;
343
                /* Miscellaneous */ case 'n':
344
                $output .= "\n";
345
                break;
346
                case 't':
347
                    $output .= "\t";
348
                    break;
349
                case '%':
350
                    $output .= '%';
351
                    break;
352
                default:
353
                    $output .= $sub;
354
            }
355
        }
356
        return ($tr_num != 'en') ? self::tr_num($output, 'fa', '.') : $output;
357
    }
358
    public static function jmktime ($hour = '', $minute = '', $second = '', $jalali_month = '', $jalali_day = '', $jalali_year = '', $none = '', $timezone = 'Asia/Tehran'): bool|int {
0 ignored issues
show
The parameter $none is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

358
    public static function jmktime ($hour = '', $minute = '', $second = '', $jalali_month = '', $jalali_day = '', $jalali_year = '', /** @scrutinizer ignore-unused */ $none = '', $timezone = 'Asia/Tehran'): bool|int {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
359
        if ($timezone != 'local') date_default_timezone_set($timezone);
360
        if ($hour === '') {
361
            return time();
362
        }
363
        else {
364
            [
365
                $hour,
366
                $minute,
367
                $second,
368
                $jalali_month,
369
                $jalali_day,
370
                $jalali_year
371
            ] = explode('_', self::tr_num($hour . '_' . $minute . '_' . $second . '_' . $jalali_month . '_' . $jalali_day . '_' . $jalali_year));
372
            if ($minute === '') {
373
                return mktime($hour);
0 ignored issues
show
$hour of type string is incompatible with the type integer expected by parameter $hour of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

373
                return mktime(/** @scrutinizer ignore-type */ $hour);
Loading history...
374
            }
375
            else {
376
                if ($second === '') {
377
                    return mktime($hour, $minute);
0 ignored issues
show
$minute of type string is incompatible with the type integer expected by parameter $minute of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

377
                    return mktime($hour, /** @scrutinizer ignore-type */ $minute);
Loading history...
378
                }
379
                else {
380
                    if ($jalali_month === '') {
381
                        return mktime($hour, $minute, $second);
0 ignored issues
show
$second of type string is incompatible with the type integer expected by parameter $second of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

381
                        return mktime($hour, $minute, /** @scrutinizer ignore-type */ $second);
Loading history...
382
                    }
383
                    else {
384
                        $jdate = explode('_', self::jdate('Y_j', '', '', $timezone, 'en'));
385
                        if ($jalali_day === '') {
386
                            [
387
                                $gregorian_year,
388
                                $gregorian_month,
389
                                $gregorian_day
390
                            ] = self::jalali_to_gregorian($jdate[0], $jalali_month, $jdate[1]);
391
                            return mktime($hour, $minute, $second, $gregorian_month);
392
                        }
393
                        else {
394
                            if ($jalali_year === '') {
395
                                [
396
                                    $gregorian_year,
397
                                    $gregorian_month,
398
                                    $gregorian_day
399
                                ] = self::jalali_to_gregorian($jdate[0], $jalali_month, $jalali_day);
400
                                return mktime($hour, $minute, $second, $gregorian_month, $gregorian_day);
401
                            }
402
                            else {
403
                                [
404
                                    $gregorian_year,
405
                                    $gregorian_month,
406
                                    $gregorian_day
407
                                ] = self::jalali_to_gregorian($jalali_year, $jalali_month, $jalali_day);
408
                                return mktime($hour, $minute, $second, $gregorian_month, $gregorian_day, $gregorian_year);
409
                            }
410
                        }
411
                    }
412
                }
413
            }
414
        }
415
    }
416
    public static function jgetdate ($timestamp = '', $none = '', $timezone = 'Asia/Tehran', $tn = 'en') {
0 ignored issues
show
The parameter $none is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

416
    public static function jgetdate ($timestamp = '', /** @scrutinizer ignore-unused */ $none = '', $timezone = 'Asia/Tehran', $tn = 'en') {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
417
        $timestamp = ($timestamp === '') ? time() : self::tr_num($timestamp);
418
        $jdate = explode('_', self::jdate('F_G_i_j_l_n_s_w_Y_z', $timestamp, '', $timezone, $tn));
419
        return [
420
            'seconds' => self::tr_num((int) self::tr_num($jdate[6]), $tn),
421
            'minutes' => self::tr_num((int) self::tr_num($jdate[2]), $tn),
422
            'hours'   => $jdate[1],
423
            'mday'    => $jdate[3],
424
            'wday'    => $jdate[7],
425
            'mon'     => $jdate[5],
426
            'year'    => $jdate[8],
427
            'yday'    => $jdate[9],
428
            'weekday' => $jdate[4],
429
            'month'   => $jdate[0],
430
            0         => self::tr_num($timestamp, $tn)
431
        ];
432
    }
433
    public static function jcheckdate ($jalali_month, $jalali_day, $jalali_year): bool {
434
        [$jalali_month, $jalali_day, $jalali_year] = explode('_', self::tr_num($jalali_month . '_' . $jalali_day . '_' . $jalali_year));
435
        $l_d = ($jalali_month == 12 and ($jalali_year + 12) % 33 % 4 != 1) ? 29 : 31 - (int) ($jalali_month / 6.5);
436
        return !(($jalali_month > 12 or $jalali_day > $l_d or $jalali_month < 1 or $jalali_day < 1 or $jalali_year < 1));
437
    }
438
    public static function tr_num ($string, $mod = 'en', $mf = '٫'): array|string {
439
        $english_number = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'];
440
        $persian_number = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹', $mf];
441
        return $mod == 'fa' ? str_replace($english_number, $persian_number, $string) : str_replace($persian_number, $english_number, $string);
442
    }
443
    public static function jdate_words ($array, $splitter = '') {
444
        foreach ($array as $type => $num) {
445
            $num = (int) self::tr_num($num);
446
            switch ($type) {
447
                case 'ss':
448
                    $length = strlen($num);
449
                    $xy3 = substr($num, 2 - $length, 1);
450
                    $h3 = $h34 = $h4 = '';
451
                    if ($xy3 == 1) {
452
                        $p34 = '';
453
                        $k34 = [
454
                            'ده',
455
                            'یازده',
456
                            'دوازده',
457
                            'سیزده',
458
                            'چهارده',
459
                            'پانزده',
460
                            'شانزده',
461
                            'هفده',
462
                            'هجده',
463
                            'نوزده'
464
                        ];
465
                        $h34 = $k34[substr($num, 2 - $length, 2) - 10];
466
                    }
467
                    else {
468
                        $xy4 = substr($num, 3 - $length, 1);
469
                        $p34 = ($xy3 == 0 or $xy4 == 0) ? '' : ' و ';
470
                        $k3 = ['', '', 'بیست', 'سی', 'چهل', 'پنجاه', 'شصت', 'هفتاد', 'هشتاد', 'نود'];
471
                        $h3 = $k3[$xy3];
472
                        $k4 = ['', 'یک', 'دو', 'سه', 'چهار', 'پنج', 'شش', 'هفت', 'هشت', 'نه'];
473
                        $h4 = $k4[$xy4];
474
                    }
475
                    $array[$type] = (($num > 99) ? str_replace(['12', '13', '14', '19', '20'], [
476
                                'هزار و دویست',
477
                                'هزار و سیصد',
478
                                'هزار و چهارصد',
479
                                'هزار و نهصد',
480
                                'دوهزار'
481
                            ], substr($num, 0, 2)) . (substr($num, 2, 2) == '00' ? '' : ' و ') : '') . $h3 . $p34 . $h34 . $h4;
482
                    break;
483
                case 'mm':
484
                    $array[$type] = [
485
                        'فروردین',
486
                        'اردیبهشت',
487
                        'خرداد',
488
                        'تیر',
489
                        'مرداد',
490
                        'شهریور',
491
                        'مهر',
492
                        'آبان',
493
                        'آذر',
494
                        'دی',
495
                        'بهمن',
496
                        'اسفند'
497
                    ][$num - 1];
498
                    break;
499
                case 'rr':
500
                    $array[$type] = [
501
                        'یک',
502
                        'دو',
503
                        'سه',
504
                        'چهار',
505
                        'پنج',
506
                        'شش',
507
                        'هفت',
508
                        'هشت',
509
                        'نه',
510
                        'ده',
511
                        'یازده',
512
                        'دوازده',
513
                        'سیزده',
514
                        'چهارده',
515
                        'پانزده',
516
                        'شانزده',
517
                        'هفده',
518
                        'هجده',
519
                        'نوزده',
520
                        'بیست',
521
                        'بیست و یک',
522
                        'بیست و دو',
523
                        'بیست و سه',
524
                        'بیست و چهار',
525
                        'بیست و پنج',
526
                        'بیست و شش',
527
                        'بیست و هفت',
528
                        'بیست و هشت',
529
                        'بیست و نه',
530
                        'سی',
531
                        'سی و یک'
532
                    ][$num - 1];
533
                    break;
534
                case 'rh':
535
                    $array[$type] = ['یکشنبه', 'دوشنبه', 'سه شنبه', 'چهارشنبه', 'پنجشنبه', 'جمعه', 'شنبه'][$num];
536
                    break;
537
                case 'sh':
538
                    $array[$type] = [
539
                        'مار',
540
                        'اسب',
541
                        'گوسفند',
542
                        'میمون',
543
                        'مرغ',
544
                        'سگ',
545
                        'خوک',
546
                        'موش',
547
                        'گاو',
548
                        'پلنگ',
549
                        'خرگوش',
550
                        'نهنگ'
551
                    ][$num % 12];
552
                    break;
553
                case 'mb':
554
                    $array[$type] = [
555
                        'حمل',
556
                        'ثور',
557
                        'جوزا',
558
                        'سرطان',
559
                        'اسد',
560
                        'سنبله',
561
                        'میزان',
562
                        'عقرب',
563
                        'قوس',
564
                        'جدی',
565
                        'دلو',
566
                        'حوت'
567
                    ][$num - 1];
568
                    break;
569
                case 'ff':
570
                    $array[$type] = ['بهار', 'تابستان', 'پاییز', 'زمستان'][(int) ($num / 3.1)];
571
                    break;
572
                case 'km':
573
                    $array[$type] = [
574
                        'فر',
575
                        'ار',
576
                        'خر',
577
                        'تی‍',
578
                        'مر',
579
                        'شه‍',
580
                        'مه‍',
581
                        'آب‍',
582
                        'آذ',
583
                        'دی',
584
                        'به‍',
585
                        'اس‍'
586
                    ][$num - 1];
587
                    break;
588
                case 'kh':
589
                    $array[$type] = ['ی', 'د', 'س', 'چ', 'پ', 'ج', 'ش'][$num];
590
                    break;
591
                default:
592
                    $array[$type] = $num;
593
            }
594
        }
595
        return $splitter === '' ? $array : implode($splitter, $array);
596
    }
597
    public static function gregorian_to_jalali ($gregorian_year, $gregorian_month, $gregorian_day, $splitter = ''): array|string {
598
        [$gregorian_year, $gregorian_month, $gregorian_day] = explode('_', self::tr_num($gregorian_year . '_' . $gregorian_month . '_' . $gregorian_day));/* <= Extra :اين سطر ، جزء تابع اصلي نيست */
599
        $g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
600
        $gregorian_year2 = ($gregorian_month > 2) ? ($gregorian_year + 1) : $gregorian_year;
601
        $days = 355666 + (365 * $gregorian_year) + ((int) (($gregorian_year2 + 3) / 4)) - ((int) (($gregorian_year2 + 99) / 100)) + ((int) (($gregorian_year2 + 399) / 400)) + $gregorian_day + $g_d_m[$gregorian_month - 1];
602
        $jalali_year = -1595 + (33 * ((int) ($days / 12053)));
603
        $days %= 12053;
604
        $jalali_year += 4 * ((int) ($days / 1461));
605
        $days %= 1461;
606
        if ($days > 365) {
607
            $jalali_year += (int) (($days - 1) / 365);
608
            $days = ($days - 1) % 365;
609
        }
610
        if ($days < 186) {
611
            $jalali_month = 1 + (int) ($days / 31);
612
            $jalali_day = 1 + ($days % 31);
613
        }
614
        else {
615
            $jalali_month = 7 + (int) (($days - 186) / 30);
616
            $jalali_day = 1 + (($days - 186) % 30);
617
        }
618
        return $splitter == '' ? [$jalali_year, $jalali_month, $jalali_day] : $jalali_year . $splitter . $jalali_month . $splitter . $jalali_day;
619
    }
620
    public static function jalali_to_gregorian ($jalali_year, $jalali_month, $jalali_day, $splitter = ''): array|string {
621
        [$jalali_year, $jalali_month, $jalali_day] = explode('_', self::tr_num($jalali_year . '_' . $jalali_month . '_' . $jalali_day));
622
        $jalali_year += 1595;
623
        $days = -355668 + (365 * $jalali_year) + (((int) ($jalali_year / 33)) * 8) + ((int) ((($jalali_year % 33) + 3) / 4)) + $jalali_day + (($jalali_month < 7) ? ($jalali_month - 1) * 31 : (($jalali_month - 7) * 30) + 186);
624
        $gregorian_year = 400 * (int) ($days / 146097);
625
        $days %= 146097;
626
        if ($days > 36524) {
627
            $gregorian_year += 100 * ((int) (--$days / 36524));
628
            $days %= 36524;
629
            if ($days >= 365) {
630
                $days++;
631
            }
632
        }
633
        $gregorian_year += 4 * ((int) ($days / 1461));
634
        $days %= 1461;
635
        if ($days > 365) {
636
            $gregorian_year += (int) (($days - 1) / 365);
637
            $days = ($days - 1) % 365;
638
        }
639
        $gregorian_day = $days + 1;
640
        $month_days = [
641
            0,
642
            31,
643
            (($gregorian_year % 4 == 0 and $gregorian_year % 100 != 0) or ($gregorian_year % 400 == 0)) ? 29 : 28,
644
            31,
645
            30,
646
            31,
647
            30,
648
            31,
649
            31,
650
            30,
651
            31,
652
            30,
653
            31
654
        ];
655
        for ($gregorian_month = 0; $gregorian_month < 13 and $gregorian_day > $month_days[$gregorian_month]; $gregorian_month++) {
656
            $gregorian_day -= $month_days[$gregorian_month];
657
        }
658
        return $splitter == '' ? [$gregorian_year, $gregorian_month, $gregorian_day] : $gregorian_year . $splitter . $gregorian_month . $splitter . $gregorian_day;
659
    }
660
}