1
|
|
|
<?php |
2
|
|
|
namespace Fisharebest\ExtCalendar; |
3
|
|
|
|
4
|
|
|
use InvalidArgumentException; |
5
|
|
|
|
6
|
|
|
/** |
7
|
|
|
* class Shim - PHP implementations of functions from the PHP calendar extension. |
8
|
|
|
* |
9
|
|
|
* @link http://php.net/manual/en/book.calendar.php |
10
|
|
|
* |
11
|
|
|
* @author Greg Roach <[email protected]> |
12
|
|
|
* @copyright (c) 2014-2020 Greg Roach |
13
|
|
|
* @license This program is free software: you can redistribute it and/or modify |
14
|
|
|
* it under the terms of the GNU General Public License as published by |
15
|
|
|
* the Free Software Foundation, either version 3 of the License, or |
16
|
|
|
* (at your option) any later version. |
17
|
|
|
* |
18
|
|
|
* This program is distributed in the hope that it will be useful, |
19
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
20
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21
|
|
|
* GNU General Public License for more details. |
22
|
|
|
* |
23
|
|
|
* You should have received a copy of the GNU General Public License |
24
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
25
|
|
|
*/ |
26
|
|
|
class Shim |
|
|
|
|
27
|
|
|
{ |
28
|
|
|
/** @var FrenchCalendar */ |
29
|
|
|
private static $french_calendar; |
30
|
|
|
|
31
|
|
|
/** @var GregorianCalendar */ |
32
|
|
|
private static $gregorian_calendar; |
33
|
|
|
|
34
|
|
|
/** @var JewishCalendar */ |
35
|
|
|
private static $jewish_calendar; |
36
|
|
|
|
37
|
|
|
/** @var JulianCalendar */ |
38
|
|
|
private static $julian_calendar; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* English names for the days of the week. |
42
|
|
|
* |
43
|
|
|
* @var string[] |
44
|
|
|
*/ |
45
|
|
|
private static $DAY_NAMES = array( |
46
|
|
|
'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', |
47
|
|
|
); |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Abbreviated English names for the days of the week. |
51
|
|
|
* |
52
|
|
|
* @var string[] |
53
|
|
|
*/ |
54
|
|
|
private static $DAY_NAMES_SHORT = array( |
55
|
|
|
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', |
56
|
|
|
); |
57
|
|
|
|
58
|
|
|
/** @var string[] Names of the months of the Gregorian/Julian calendars */ |
59
|
|
|
private static $MONTH_NAMES = array( |
60
|
|
|
'', 'January', 'February', 'March', 'April', 'May', 'June', |
61
|
|
|
'July', 'August', 'September', 'October', 'November', 'December', |
62
|
|
|
); |
63
|
|
|
|
64
|
|
|
/** @var string[] Abbreviated names of the months of the Gregorian/Julian calendars */ |
65
|
|
|
private static $MONTH_NAMES_SHORT = array( |
66
|
|
|
'', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', |
67
|
|
|
); |
68
|
|
|
|
69
|
|
|
/** @var string[] Name of the months of the French calendar */ |
70
|
|
|
private static $MONTH_NAMES_FRENCH = array( |
71
|
|
|
'', 'Vendemiaire', 'Brumaire', 'Frimaire', 'Nivose', 'Pluviose', 'Ventose', |
72
|
|
|
'Germinal', 'Floreal', 'Prairial', 'Messidor', 'Thermidor', 'Fructidor', 'Extra' |
73
|
|
|
); |
74
|
|
|
|
75
|
|
|
/** @var string[] Names of the months of the Jewish calendar in a non-leap year */ |
76
|
|
|
private static $MONTH_NAMES_JEWISH = array( |
77
|
|
|
'', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar', |
78
|
|
|
'Adar', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
79
|
|
|
); |
80
|
|
|
|
81
|
|
|
/** @var string[] Names of the months of the Jewish calendar in a leap year */ |
82
|
|
|
private static $MONTH_NAMES_JEWISH_LEAP_YEAR = array( |
83
|
|
|
'', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'Adar I', |
84
|
|
|
'Adar II', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
85
|
|
|
); |
86
|
|
|
|
87
|
|
|
/** @var string[] Names of the months of the Jewish calendar (before PHP bug 54254 was fixed) */ |
88
|
|
|
private static $MONTH_NAMES_JEWISH_54254 = array( |
89
|
|
|
'', 'Tishri', 'Heshvan', 'Kislev', 'Tevet', 'Shevat', 'AdarI', |
90
|
|
|
'AdarII', 'Nisan', 'Iyyar', 'Sivan', 'Tammuz', 'Av', 'Elul', |
91
|
|
|
); |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Create the necessary shims to emulate the ext/calendar package. |
95
|
|
|
* |
96
|
|
|
* @return void |
97
|
|
|
*/ |
98
|
|
|
public static function create() |
99
|
|
|
{ |
100
|
|
|
self::$french_calendar = new FrenchCalendar(); |
101
|
|
|
self::$gregorian_calendar = new GregorianCalendar(); |
102
|
|
|
self::$jewish_calendar = new JewishCalendar(array( |
103
|
|
|
JewishCalendar::EMULATE_BUG_54254 => self::shouldEmulateBug54254(), |
104
|
|
|
)); |
105
|
|
|
self::$julian_calendar = new JulianCalendar(); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Do we need to emulate PHP bug #54254? |
110
|
|
|
* |
111
|
|
|
* This bug relates to the names used for months 6 and 7 in the Jewish calendar. |
112
|
|
|
* |
113
|
|
|
* It was fixed in PHP 5.5.0 |
114
|
|
|
* |
115
|
|
|
* @link https://bugs.php.net/bug.php?id=54254 |
116
|
|
|
* |
117
|
|
|
* @return bool |
118
|
|
|
*/ |
119
|
|
|
public static function shouldEmulateBug54254() |
120
|
|
|
{ |
121
|
|
|
return version_compare(PHP_VERSION, '5.5.0', '<'); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Do we need to emulate PHP bug #67960? |
126
|
|
|
* |
127
|
|
|
* This bug relates to the constants CAL_DOW_SHORT and CAL_DOW_LONG. |
128
|
|
|
* |
129
|
|
|
* It was fixed in PHP 5.6.5 and 5.5.21 |
130
|
|
|
* |
131
|
|
|
* @link https://bugs.php.net/bug.php?id=67960 |
132
|
|
|
* @link https://github.com/php/php-src/pull/806 |
133
|
|
|
* |
134
|
|
|
* @return bool |
135
|
|
|
*/ |
136
|
|
|
public static function shouldEmulateBug67960() |
137
|
|
|
{ |
138
|
|
|
return version_compare(PHP_VERSION, '5.5.21', '<') || version_compare(PHP_VERSION, '5.6.0', '>=') && version_compare(PHP_VERSION, '5.6.5', '<') ; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Do we need to emulate PHP bug #67976? |
143
|
|
|
* |
144
|
|
|
* This bug relates to the number of days in the month 13 of year 14 in |
145
|
|
|
* the French calendar. |
146
|
|
|
* |
147
|
|
|
* It was fixed in PHP 5.6.25 and 7.0.10 |
148
|
|
|
* |
149
|
|
|
* @link https://bugs.php.net/bug.php?id=67976 |
150
|
|
|
* |
151
|
|
|
* @return bool |
152
|
|
|
*/ |
153
|
|
|
public static function shouldEmulateBug67976() |
154
|
|
|
{ |
155
|
|
|
return version_compare(PHP_VERSION, '5.6.25', '<') || version_compare(PHP_VERSION, '7.0.0', '>=') && version_compare(PHP_VERSION, '7.0.10', '<') ; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Return the number of days in a month for a given year and calendar. |
160
|
|
|
* |
161
|
|
|
* Shim implementation of cal_days_in_month() |
162
|
|
|
* |
163
|
|
|
* @link https://php.net/cal_days_in_month |
164
|
|
|
* @link https://bugs.php.net/bug.php?id=67976 |
165
|
|
|
* |
166
|
|
|
* @param int $calendar_id |
167
|
|
|
* @param int $month |
168
|
|
|
* @param int $year |
169
|
|
|
* |
170
|
|
|
* @return int|bool The number of days in the specified month, or false on error |
171
|
|
|
*/ |
172
|
|
|
public static function calDaysInMonth($calendar_id, $month, $year) |
173
|
|
|
{ |
174
|
|
|
switch ($calendar_id) { |
175
|
|
|
case CAL_FRENCH: |
176
|
|
|
return self::calDaysInMonthFrench($year, $month); |
177
|
|
|
|
178
|
|
|
case CAL_GREGORIAN: |
179
|
|
|
return self::calDaysInMonthCalendar(self::$gregorian_calendar, $year, $month); |
180
|
|
|
|
181
|
|
|
case CAL_JEWISH: |
182
|
|
|
return self::calDaysInMonthCalendar(self::$jewish_calendar, $year, $month); |
183
|
|
|
|
184
|
|
|
case CAL_JULIAN: |
185
|
|
|
return self::calDaysInMonthCalendar(self::$julian_calendar, $year, $month); |
186
|
|
|
|
187
|
|
|
default: |
188
|
|
|
return trigger_error('invalid calendar ID ' . $calendar_id, E_USER_WARNING); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Calculate the number of days in a month in a specified (Gregorian or Julian) calendar. |
194
|
|
|
* |
195
|
|
|
* @param CalendarInterface $calendar |
196
|
|
|
* @param int $year |
197
|
|
|
* @param int $month |
198
|
|
|
* |
199
|
|
|
* @return int|bool |
200
|
|
|
*/ |
201
|
|
|
private static function calDaysInMonthCalendar(CalendarInterface $calendar, $year, $month) |
202
|
|
|
{ |
203
|
|
|
try { |
204
|
|
|
return $calendar->daysInMonth($year, $month); |
205
|
|
|
} catch (InvalidArgumentException $ex) { |
206
|
|
|
$error_msg = PHP_VERSION_ID < 70200 ? 'invalid date.' : 'invalid date'; |
207
|
|
|
|
208
|
|
|
return trigger_error($error_msg, E_USER_WARNING); |
209
|
|
|
} |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Calculate the number of days in a month in the French calendar. |
214
|
|
|
* |
215
|
|
|
* Mimic PHP’s validation of the parameters |
216
|
|
|
* |
217
|
|
|
* @param int $year |
218
|
|
|
* @param int $month |
219
|
|
|
* |
220
|
|
|
* @return int|bool |
221
|
|
|
*/ |
222
|
|
|
private static function calDaysInMonthFrench($year, $month) |
223
|
|
|
{ |
224
|
|
|
if ($month == 13 && $year == 14 && self::shouldEmulateBug67976()) { |
225
|
|
|
return -2380948; |
226
|
|
View Code Duplication |
} elseif ($year > 14) { |
|
|
|
|
227
|
|
|
$error_msg = PHP_VERSION_ID < 70200 ? 'invalid date.' : 'invalid date'; |
228
|
|
|
|
229
|
|
|
return trigger_error($error_msg, E_USER_WARNING); |
230
|
|
|
} else { |
231
|
|
|
return self::calDaysInMonthCalendar(self::$french_calendar, $year, $month); |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* Converts from Julian Day Count to a supported calendar. |
237
|
|
|
* |
238
|
|
|
* Shim implementation of cal_from_jd() |
239
|
|
|
* |
240
|
|
|
* @link https://php.net/cal_from_jd |
241
|
|
|
* |
242
|
|
|
* @param int $julian_day Julian Day number |
243
|
|
|
* @param int $calendar_id Calendar constant |
244
|
|
|
* |
245
|
|
|
* @return array|bool |
|
|
|
|
246
|
|
|
*/ |
247
|
|
|
public static function calFromJd($julian_day, $calendar_id) |
248
|
|
|
{ |
249
|
|
|
switch ($calendar_id) { |
250
|
|
|
case CAL_FRENCH: |
251
|
|
|
return self::calFromJdCalendar($julian_day, self::jdToFrench($julian_day), self::$MONTH_NAMES_FRENCH, self::$MONTH_NAMES_FRENCH); |
252
|
|
|
|
253
|
|
|
case CAL_GREGORIAN: |
254
|
|
|
return self::calFromJdCalendar($julian_day, self::jdToGregorian($julian_day), self::$MONTH_NAMES, self::$MONTH_NAMES_SHORT); |
255
|
|
|
|
256
|
|
|
case CAL_JEWISH: |
257
|
|
|
$months = self::jdMonthNameJewishMonths($julian_day); |
258
|
|
|
|
259
|
|
|
$cal = self::calFromJdCalendar($julian_day, self::jdToCalendar(self::$jewish_calendar, $julian_day, 347998, 324542846), $months, $months); |
260
|
|
|
|
261
|
|
|
if (($julian_day < 347998 || $julian_day > 324542846) && !self::shouldEmulateBug67976()) { |
262
|
|
|
$cal['dow'] = null; |
263
|
|
|
$cal['dayname'] = ''; |
264
|
|
|
$cal['abbrevdayname'] = ''; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
return $cal; |
268
|
|
|
|
269
|
|
|
case CAL_JULIAN: |
270
|
|
|
return self::calFromJdCalendar($julian_day, self::jdToJulian($julian_day), self::$MONTH_NAMES, self::$MONTH_NAMES_SHORT); |
271
|
|
|
|
272
|
|
|
default: |
273
|
|
|
return trigger_error('invalid calendar ID ' . $calendar_id, E_USER_WARNING); |
274
|
|
|
} |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Convert a Julian day number to a calendar and provide details. |
279
|
|
|
* |
280
|
|
|
* @param int $julian_day |
281
|
|
|
* @param string $mdy |
282
|
|
|
* @param string[] $months |
283
|
|
|
* @param string[] $months_short |
284
|
|
|
* |
285
|
|
|
* @return array |
|
|
|
|
286
|
|
|
*/ |
287
|
|
|
private static function calFromJdCalendar($julian_day, $mdy, $months, $months_short) |
288
|
|
|
{ |
289
|
|
|
list($month, $day, $year) = explode('/', $mdy); |
290
|
|
|
|
291
|
|
|
return array( |
292
|
|
|
'date' => $month . '/' . $day . '/' . $year, |
293
|
|
|
'month' => (int) $month, |
294
|
|
|
'day' => (int) $day, |
295
|
|
|
'year' => (int) $year, |
296
|
|
|
'dow' => self::jdDayOfWeek($julian_day, 0), |
297
|
|
|
'abbrevdayname' => self::jdDayOfWeek($julian_day, 2), |
298
|
|
|
'dayname' => self::jdDayOfWeek($julian_day, 1), |
299
|
|
|
'abbrevmonth' => $months_short[$month], |
300
|
|
|
'monthname' => $months[$month], |
301
|
|
|
); |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* Returns information about a particular calendar. |
306
|
|
|
* |
307
|
|
|
* Shim implementation of cal_info() |
308
|
|
|
* |
309
|
|
|
* @link https://php.net/cal_info |
310
|
|
|
* |
311
|
|
|
* @param int $calendar_id |
312
|
|
|
* |
313
|
|
|
* @return array|bool |
|
|
|
|
314
|
|
|
*/ |
315
|
|
|
public static function calInfo($calendar_id) |
316
|
|
|
{ |
317
|
|
|
switch ($calendar_id) { |
318
|
|
|
case CAL_FRENCH: |
319
|
|
|
return self::calInfoCalendar(self::$MONTH_NAMES_FRENCH, self::$MONTH_NAMES_FRENCH, 30, 'French', 'CAL_FRENCH'); |
320
|
|
|
|
321
|
|
|
case CAL_GREGORIAN: |
322
|
|
|
return self::calInfoCalendar(self::$MONTH_NAMES, self::$MONTH_NAMES_SHORT, 31, 'Gregorian', 'CAL_GREGORIAN'); |
323
|
|
|
|
324
|
|
|
case CAL_JEWISH: |
325
|
|
|
$months = self::shouldEmulateBug54254() ? self::$MONTH_NAMES_JEWISH_54254 : self::$MONTH_NAMES_JEWISH_LEAP_YEAR; |
326
|
|
|
|
327
|
|
|
return self::calInfoCalendar($months, $months, 30, 'Jewish', 'CAL_JEWISH'); |
328
|
|
|
|
329
|
|
|
case CAL_JULIAN: |
330
|
|
|
return self::calInfoCalendar(self::$MONTH_NAMES, self::$MONTH_NAMES_SHORT, 31, 'Julian', 'CAL_JULIAN'); |
331
|
|
|
|
332
|
|
|
case -1: |
333
|
|
|
return array( |
334
|
|
|
CAL_GREGORIAN => self::calInfo(CAL_GREGORIAN), |
335
|
|
|
CAL_JULIAN => self::calInfo(CAL_JULIAN), |
336
|
|
|
CAL_JEWISH => self::calInfo(CAL_JEWISH), |
337
|
|
|
CAL_FRENCH => self::calInfo(CAL_FRENCH), |
338
|
|
|
); |
339
|
|
|
|
340
|
|
|
default: |
341
|
|
|
return trigger_error('invalid calendar ID ' . $calendar_id, E_USER_WARNING); |
342
|
|
|
} |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
/** |
346
|
|
|
* Returns information about the French calendar. |
347
|
|
|
* |
348
|
|
|
* @param string[] $month_names |
349
|
|
|
* @param string[] $month_names_short |
350
|
|
|
* @param int $max_days_in_month |
351
|
|
|
* @param string $calendar_name |
352
|
|
|
* @param string $calendar_symbol |
353
|
|
|
* |
354
|
|
|
* @return array |
|
|
|
|
355
|
|
|
*/ |
356
|
|
|
private static function calInfoCalendar($month_names, $month_names_short, $max_days_in_month, $calendar_name, $calendar_symbol) |
357
|
|
|
{ |
358
|
|
|
return array( |
359
|
|
|
'months' => array_slice($month_names, 1, null, true), |
360
|
|
|
'abbrevmonths' => array_slice($month_names_short, 1, null, true), |
361
|
|
|
'maxdaysinmonth' => $max_days_in_month, |
362
|
|
|
'calname' => $calendar_name, |
363
|
|
|
'calsymbol' => $calendar_symbol, |
364
|
|
|
); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* Converts from a supported calendar to Julian Day Count |
369
|
|
|
* |
370
|
|
|
* Shim implementation of cal_to_jd() |
371
|
|
|
* |
372
|
|
|
* @link https://php.net/cal_to_jd |
373
|
|
|
* |
374
|
|
|
* @param int $calendar_id |
375
|
|
|
* @param int $month |
376
|
|
|
* @param int $day |
377
|
|
|
* @param int $year |
378
|
|
|
* |
379
|
|
|
* @return int|bool |
380
|
|
|
*/ |
381
|
|
|
public static function calToJd($calendar_id, $month, $day, $year) |
382
|
|
|
{ |
383
|
|
|
switch ($calendar_id) { |
384
|
|
|
case CAL_FRENCH: |
385
|
|
|
return self::frenchToJd($month, $day, $year); |
386
|
|
|
|
387
|
|
|
case CAL_GREGORIAN: |
388
|
|
|
return self::gregorianToJd($month, $day, $year); |
389
|
|
|
|
390
|
|
|
case CAL_JEWISH: |
391
|
|
|
return self::jewishToJd($month, $day, $year); |
392
|
|
|
|
393
|
|
|
case CAL_JULIAN: |
394
|
|
|
return self::julianToJd($month, $day, $year); |
395
|
|
|
|
396
|
|
|
default: |
397
|
|
|
return trigger_error('invalid calendar ID ' . $calendar_id . '.', E_USER_WARNING); |
398
|
|
|
} |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Get Unix timestamp for midnight on Easter of a given year. |
403
|
|
|
* |
404
|
|
|
* Shim implementation of easter_date() |
405
|
|
|
* |
406
|
|
|
* @link https://php.net/easter_date |
407
|
|
|
* |
408
|
|
|
* @param int $year |
409
|
|
|
* |
410
|
|
|
* @return int|bool |
|
|
|
|
411
|
|
|
*/ |
412
|
|
|
public static function easterDate($year) |
413
|
|
|
{ |
414
|
|
|
if ($year < 1970 || $year > 2037) { |
415
|
|
|
return trigger_error('This function is only valid for years between 1970 and 2037 inclusive', E_USER_WARNING); |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
$days = self::$gregorian_calendar->easterDays($year); |
419
|
|
|
|
420
|
|
|
// Calculate time-zone offset |
421
|
|
|
$date_time = new \DateTime('now', new \DateTimeZone(date_default_timezone_get())); |
422
|
|
|
$offset_seconds = (int) $date_time->format('Z'); |
423
|
|
|
|
424
|
|
|
if ($days < 11) { |
425
|
|
|
return self::jdtounix(self::$gregorian_calendar->ymdToJd($year, 3, $days + 21)) - $offset_seconds; |
426
|
|
|
} else { |
427
|
|
|
return self::jdtounix(self::$gregorian_calendar->ymdToJd($year, 4, $days - 10)) - $offset_seconds; |
428
|
|
|
} |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* Get number of days after March 21 on which Easter falls for a given year. |
433
|
|
|
* |
434
|
|
|
* Shim implementation of easter_days() |
435
|
|
|
* |
436
|
|
|
* @link https://php.net/easter_days |
437
|
|
|
* |
438
|
|
|
* @param int $year |
439
|
|
|
* @param int $method Use the Julian or Gregorian calendar |
440
|
|
|
* |
441
|
|
|
* @return int |
442
|
|
|
*/ |
443
|
|
|
public static function easterDays($year, $method) |
444
|
|
|
{ |
445
|
|
|
if ($method == CAL_EASTER_ALWAYS_JULIAN || |
446
|
|
|
$method == CAL_EASTER_ROMAN && $year <= 1582 || |
447
|
|
|
$year <= 1752 && $method != CAL_EASTER_ROMAN && $method != CAL_EASTER_ALWAYS_GREGORIAN |
448
|
|
|
) { |
449
|
|
|
return self::$julian_calendar->easterDays($year); |
450
|
|
|
} else { |
451
|
|
|
return self::$gregorian_calendar->easterDays($year); |
452
|
|
|
} |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* Converts a date from the French Republican Calendar to a Julian Day Count. |
457
|
|
|
* |
458
|
|
|
* Shim implementation of FrenchToJD() |
459
|
|
|
* |
460
|
|
|
* @link https://php.net/FrenchToJD |
461
|
|
|
* |
462
|
|
|
* @param int $month |
463
|
|
|
* @param int $day |
464
|
|
|
* @param int $year |
465
|
|
|
* |
466
|
|
|
* @return int |
467
|
|
|
*/ |
468
|
|
|
public static function frenchToJd($month, $day, $year) |
469
|
|
|
{ |
470
|
|
|
if ($year <= 0) { |
471
|
|
|
return 0; |
472
|
|
|
} else { |
473
|
|
|
return self::$french_calendar->ymdToJd($year, $month, $day); |
474
|
|
|
} |
475
|
|
|
} |
476
|
|
|
|
477
|
|
|
/** |
478
|
|
|
* Converts a Gregorian date to Julian Day Count. |
479
|
|
|
* |
480
|
|
|
* Shim implementation of GregorianToJD() |
481
|
|
|
* |
482
|
|
|
* @link https://php.net/GregorianToJD |
483
|
|
|
* |
484
|
|
|
* @param int $month |
485
|
|
|
* @param int $day |
486
|
|
|
* @param int $year |
487
|
|
|
* |
488
|
|
|
* @return int |
489
|
|
|
*/ |
490
|
|
|
public static function gregorianToJd($month, $day, $year) |
491
|
|
|
{ |
492
|
|
|
if ($year == 0) { |
493
|
|
|
return 0; |
494
|
|
|
} else { |
495
|
|
|
return self::$gregorian_calendar->ymdToJd($year, $month, $day); |
496
|
|
|
} |
497
|
|
|
} |
498
|
|
|
|
499
|
|
|
/** |
500
|
|
|
* Returns the day of the week. |
501
|
|
|
* |
502
|
|
|
* Shim implementation of JDDayOfWeek() |
503
|
|
|
* |
504
|
|
|
* @link https://php.net/JDDayOfWeek |
505
|
|
|
* @link https://bugs.php.net/bug.php?id=67960 |
506
|
|
|
* |
507
|
|
|
* @param int $julian_day |
508
|
|
|
* @param int $mode |
509
|
|
|
* |
510
|
|
|
* @return int|string |
511
|
|
|
*/ |
512
|
|
|
public static function jdDayOfWeek($julian_day, $mode) |
513
|
|
|
{ |
514
|
|
|
$day_of_week = ($julian_day + 1) % 7; |
515
|
|
|
if ($day_of_week < 0) { |
516
|
|
|
$day_of_week += 7; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
switch ($mode) { |
520
|
|
|
case 1: // 1, not CAL_DOW_LONG - see bug 67960 |
521
|
|
|
return self::$DAY_NAMES[$day_of_week]; |
522
|
|
|
|
523
|
|
|
case 2: // 2, not CAL_DOW_SHORT - see bug 67960 |
524
|
|
|
return self::$DAY_NAMES_SHORT[$day_of_week]; |
525
|
|
|
|
526
|
|
|
default: // CAL_DOW_DAYNO or anything else |
527
|
|
|
return $day_of_week; |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* Returns a month name. |
533
|
|
|
* |
534
|
|
|
* Shim implementation of JDMonthName() |
535
|
|
|
* |
536
|
|
|
* @link https://php.net/JDMonthName |
537
|
|
|
* |
538
|
|
|
* @param int $julian_day |
539
|
|
|
* @param int $mode |
540
|
|
|
* |
541
|
|
|
* @return string |
542
|
|
|
*/ |
543
|
|
|
public static function jdMonthName($julian_day, $mode) |
544
|
|
|
{ |
545
|
|
|
switch ($mode) { |
546
|
|
|
case CAL_MONTH_GREGORIAN_LONG: |
547
|
|
|
return self::jdMonthNameCalendar(self::$gregorian_calendar, $julian_day, self::$MONTH_NAMES); |
548
|
|
|
|
549
|
|
|
case CAL_MONTH_JULIAN_LONG: |
550
|
|
|
return self::jdMonthNameCalendar(self::$julian_calendar, $julian_day, self::$MONTH_NAMES); |
551
|
|
|
|
552
|
|
|
case CAL_MONTH_JULIAN_SHORT: |
553
|
|
|
return self::jdMonthNameCalendar(self::$julian_calendar, $julian_day, self::$MONTH_NAMES_SHORT); |
554
|
|
|
|
555
|
|
|
case CAL_MONTH_JEWISH: |
556
|
|
|
return self::jdMonthNameCalendar(self::$jewish_calendar, $julian_day, self::jdMonthNameJewishMonths($julian_day)); |
557
|
|
|
|
558
|
|
|
case CAL_MONTH_FRENCH: |
559
|
|
|
return self::jdMonthNameCalendar(self::$french_calendar, $julian_day, self::$MONTH_NAMES_FRENCH); |
560
|
|
|
|
561
|
|
|
case CAL_MONTH_GREGORIAN_SHORT: |
562
|
|
|
default: |
563
|
|
|
return self::jdMonthNameCalendar(self::$gregorian_calendar, $julian_day, self::$MONTH_NAMES_SHORT); |
564
|
|
|
} |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
/** |
568
|
|
|
* Calculate the month-name for a given julian day, in a given calendar, |
569
|
|
|
* with given set of month names. |
570
|
|
|
* |
571
|
|
|
* @param CalendarInterface $calendar |
572
|
|
|
* @param int $julian_day |
573
|
|
|
* @param string[] $months |
574
|
|
|
* |
575
|
|
|
* @return string |
576
|
|
|
*/ |
577
|
|
|
private static function jdMonthNameCalendar(CalendarInterface $calendar, $julian_day, $months) |
578
|
|
|
{ |
579
|
|
|
list(, $month) = $calendar->jdToYmd($julian_day); |
580
|
|
|
|
581
|
|
|
return $months[$month]; |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
/** |
585
|
|
|
* Determine which month names to use for the Jewish calendar. |
586
|
|
|
* |
587
|
|
|
* @param int $julian_day |
588
|
|
|
* |
589
|
|
|
* @return string[] |
590
|
|
|
*/ |
591
|
|
|
private static function jdMonthNameJewishMonths($julian_day) |
592
|
|
|
{ |
593
|
|
|
list(, , $year) = explode('/', self::jdToCalendar(self::$jewish_calendar, $julian_day, 347998, 324542846)); |
594
|
|
|
|
595
|
|
|
if (self::$jewish_calendar->isLeapYear($year)) { |
596
|
|
|
return self::shouldEmulateBug54254() ? self::$MONTH_NAMES_JEWISH_54254 : self::$MONTH_NAMES_JEWISH_LEAP_YEAR; |
597
|
|
|
} else { |
598
|
|
|
return self::shouldEmulateBug54254() ? self::$MONTH_NAMES_JEWISH_54254 : self::$MONTH_NAMES_JEWISH; |
599
|
|
|
} |
600
|
|
|
} |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* Convert a Julian day in a specific calendar to a day/month/year. |
604
|
|
|
* |
605
|
|
|
* Julian days outside the specified range are returned as “0/0/0”. |
606
|
|
|
* |
607
|
|
|
* @param CalendarInterface $calendar |
608
|
|
|
* @param int $julian_day |
609
|
|
|
* @param int $min_jd |
610
|
|
|
* @param int $max_jd |
611
|
|
|
* |
612
|
|
|
* @return string |
613
|
|
|
*/ |
614
|
|
|
private static function jdToCalendar(CalendarInterface $calendar, $julian_day, $min_jd, $max_jd) |
615
|
|
|
{ |
616
|
|
|
if ($julian_day >= $min_jd && $julian_day <= $max_jd) { |
617
|
|
|
list($year, $month, $day) = $calendar->jdToYmd($julian_day); |
618
|
|
|
|
619
|
|
|
return $month . '/' . $day . '/' . $year; |
620
|
|
|
} else { |
621
|
|
|
return '0/0/0'; |
622
|
|
|
} |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* Converts a Julian Day Count to the French Republican Calendar. |
627
|
|
|
* |
628
|
|
|
* Shim implementation of JDToFrench() |
629
|
|
|
* |
630
|
|
|
* @link https://php.net/JDToFrench |
631
|
|
|
* |
632
|
|
|
* @param int $julian_day A Julian Day number |
633
|
|
|
* |
634
|
|
|
* @return string A string of the form "month/day/year" |
635
|
|
|
*/ |
636
|
|
|
public static function jdToFrench($julian_day) |
637
|
|
|
{ |
638
|
|
|
// JDToFrench() converts years 1 to 14 inclusive, even though the calendar |
639
|
|
|
// officially ended on 10 Nivôse 14 (JD 2380687, 31st December 1805 Gregorian). |
640
|
|
|
return self::jdToCalendar(self::$french_calendar, $julian_day, 2375840, 2380952); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
/** |
644
|
|
|
* Converts Julian Day Count to Gregorian date. |
645
|
|
|
* |
646
|
|
|
* Shim implementation of JDToGregorian() |
647
|
|
|
* |
648
|
|
|
* @link https://php.net/JDToGregorian |
649
|
|
|
* |
650
|
|
|
* @param int $julian_day A Julian Day number |
651
|
|
|
* |
652
|
|
|
* @return string A string of the form "month/day/year" |
653
|
|
|
*/ |
654
|
|
View Code Duplication |
public static function jdToGregorian($julian_day) |
|
|
|
|
655
|
|
|
{ |
656
|
|
|
// PHP has different limits on 32 and 64 bit systems. |
657
|
|
|
$MAX_JD = PHP_INT_SIZE == 4 ? 536838866 : 2305843009213661906; |
658
|
|
|
|
659
|
|
|
return self::jdToCalendar(self::$gregorian_calendar, $julian_day, 1, $MAX_JD); |
660
|
|
|
} |
661
|
|
|
|
662
|
|
|
/** |
663
|
|
|
* Converts a Julian day count to a Jewish calendar date. |
664
|
|
|
* |
665
|
|
|
* Shim implementation of JdtoJjewish() |
666
|
|
|
* |
667
|
|
|
* @link https://php.net/JdtoJewish |
668
|
|
|
* |
669
|
|
|
* @param int $julian_day A Julian Day number |
670
|
|
|
* @param bool $hebrew If true, the date is returned in Hebrew text |
671
|
|
|
* @param int $fl If $hebrew is true, then add alafim and gereshayim to the text |
672
|
|
|
* |
673
|
|
|
* @return string|bool A string of the form "month/day/year", or false on error |
674
|
|
|
*/ |
675
|
|
|
public static function jdToJewish($julian_day, $hebrew, $fl) |
676
|
|
|
{ |
677
|
|
|
if ($hebrew) { |
678
|
|
View Code Duplication |
if ($julian_day < 347998 || $julian_day > 4000075) { |
|
|
|
|
679
|
|
|
$error_msg = PHP_VERSION_ID < 70200 ? 'Year out of range (0-9999).' : 'Year out of range (0-9999)'; |
680
|
|
|
|
681
|
|
|
return trigger_error($error_msg, E_USER_WARNING); |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
return self::$jewish_calendar->jdToHebrew( |
685
|
|
|
$julian_day, |
686
|
|
|
(bool)($fl & CAL_JEWISH_ADD_ALAFIM_GERESH), |
687
|
|
|
(bool)($fl & CAL_JEWISH_ADD_ALAFIM), |
688
|
|
|
(bool)($fl & CAL_JEWISH_ADD_GERESHAYIM) |
689
|
|
|
); |
690
|
|
|
} else { |
691
|
|
|
// The upper limit is hard-coded into PHP to prevent numeric overflow on 32 bit systems. |
692
|
|
|
return self::jdToCalendar(self::$jewish_calendar, $julian_day, 347998, 324542846); |
693
|
|
|
} |
694
|
|
|
} |
695
|
|
|
|
696
|
|
|
/** |
697
|
|
|
* Converts a Julian Day Count to a Julian Calendar Date. |
698
|
|
|
* |
699
|
|
|
* Shim implementation of JDToJulian() |
700
|
|
|
* |
701
|
|
|
* @link https://php.net/JDToJulian |
702
|
|
|
* |
703
|
|
|
* @param int $julian_day A Julian Day number |
704
|
|
|
* |
705
|
|
|
* @return string A string of the form "month/day/year" |
706
|
|
|
*/ |
707
|
|
View Code Duplication |
public static function jdToJulian($julian_day) |
|
|
|
|
708
|
|
|
{ |
709
|
|
|
// PHP has different limits on 32 and 64 bit systems. |
710
|
|
|
$MAX_JD = PHP_INT_SIZE == 4 ? 536838829 : 784368370349; |
711
|
|
|
|
712
|
|
|
return self::jdToCalendar(self::$julian_calendar, $julian_day, 1, $MAX_JD); |
713
|
|
|
} |
714
|
|
|
|
715
|
|
|
/** |
716
|
|
|
* Convert Julian Day to Unix timestamp. |
717
|
|
|
* |
718
|
|
|
* Shim implementation of jdtounix() |
719
|
|
|
* |
720
|
|
|
* @link https://php.net/jdtounix |
721
|
|
|
* |
722
|
|
|
* @param int $julian_day |
723
|
|
|
* |
724
|
|
|
* @return int|false |
725
|
|
|
*/ |
726
|
|
|
public static function jdToUnix($julian_day) |
727
|
|
|
{ |
728
|
|
|
if ($julian_day >= 2440588 && $julian_day <= 2465343) { |
729
|
|
|
return (int) ($julian_day - 2440588) * 86400; |
730
|
|
|
} else { |
731
|
|
|
return false; |
732
|
|
|
} |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* Converts a date in the Jewish Calendar to Julian Day Count. |
737
|
|
|
* |
738
|
|
|
* Shim implementation of JewishToJD() |
739
|
|
|
* |
740
|
|
|
* @link https://php.net/JewishToJD |
741
|
|
|
* |
742
|
|
|
* @param int $month |
743
|
|
|
* @param int $day |
744
|
|
|
* @param int $year |
745
|
|
|
* |
746
|
|
|
* @return int |
747
|
|
|
*/ |
748
|
|
|
public static function jewishToJd($month, $day, $year) |
749
|
|
|
{ |
750
|
|
|
if ($year <= 0) { |
751
|
|
|
return 0; |
752
|
|
|
} else { |
753
|
|
|
return self::$jewish_calendar->ymdToJd($year, $month, $day); |
754
|
|
|
} |
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
/** |
758
|
|
|
* Converts a Julian Calendar date to Julian Day Count. |
759
|
|
|
* |
760
|
|
|
* Shim implementation of JdToJulian() |
761
|
|
|
* |
762
|
|
|
* @link https://php.net/JdToJulian |
763
|
|
|
* |
764
|
|
|
* @param int $month |
765
|
|
|
* @param int $day |
766
|
|
|
* @param int $year |
767
|
|
|
* |
768
|
|
|
* @return int |
769
|
|
|
*/ |
770
|
|
|
public static function julianToJd($month, $day, $year) |
771
|
|
|
{ |
772
|
|
|
if ($year == 0) { |
773
|
|
|
return 0; |
774
|
|
|
} else { |
775
|
|
|
return self::$julian_calendar->ymdToJd($year, $month, $day); |
776
|
|
|
} |
777
|
|
|
} |
778
|
|
|
|
779
|
|
|
/** |
780
|
|
|
* Convert Unix timestamp to Julian Day. |
781
|
|
|
* |
782
|
|
|
* Shim implementation of unixtojd() |
783
|
|
|
* |
784
|
|
|
* @link https://php.net/unixtojd |
785
|
|
|
* |
786
|
|
|
* @param int $timestamp |
787
|
|
|
* |
788
|
|
|
* @return false|int |
789
|
|
|
*/ |
790
|
|
|
public static function unixToJd($timestamp) |
791
|
|
|
{ |
792
|
|
|
if ($timestamp < 0) { |
793
|
|
|
return false; |
794
|
|
|
} else { |
795
|
|
|
// Convert timestamp based on local timezone |
796
|
|
|
return self::GregorianToJd(gmdate('n', $timestamp), gmdate('j', $timestamp), gmdate('Y', $timestamp)); |
797
|
|
|
} |
798
|
|
|
} |
799
|
|
|
} |
800
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.