All guides
No guide matches your search.
Limits
Every hard limit in one place. Supported year ranges, input size caps, number-word ranges, the Umm al-Qura range, tuning ranges and the other numeric boundaries of the library.
On this page
These limits are on purpose. They keep every call cheap and predictable, and they stop untrusted input from turning into a wrapped-around date or an expensive computation. Going over a limit always raises a documented RtlyKitException (see Error handling) or, for validators, gives an invalid Result.
Calendar year ranges
Every supported date of every calendar maps to a Gregorian year between 1 and 9999. So any value the classes produce fits in a DateTimeImmutable without wrapping around. The ranges are the public constants MIN_YEAR and MAX_YEAR:
| Calendar | MIN_YEAR | MAX_YEAR | Gregorian date of 1/1 of those years |
|---|---|---|---|
Jalali | -620 | 9377 | 0001-03-21 .. 9998-03-20 |
Hijri | 1 | 9665 | 0622-07-19 .. 9998-10-12 |
Hebrew | 3762 | 13759 | 0001-09-06 .. 9998-10-15 |
<?php
require __DIR__.'/vendor/autoload.php';
use RtlyKit\Calendar\{Hebrew, Hijri, Jalali};
foreach ([Jalali::class, Hijri::class, Hebrew::class] as $class) {
printf(
"%-7s %5d..%-5d %s .. %s\n",
(new ReflectionClass($class))->getShortName(),
$class::MIN_YEAR,
$class::MAX_YEAR,
$class::create($class::MIN_YEAR, 1, 1)->toGregorian()->format('Y-m-d'),
$class::create($class::MAX_YEAR, 1, 1)->toGregorian()->format('Y-m-d'),
);
}
// Jalali -620..9377 0001-03-21 .. 9998-03-20
// Hijri 1..9665 0622-07-19 .. 9998-10-12
// Hebrew 3762..13759 0001-09-06 .. 9998-10-15Every entry point follows the range: make, create, createFromFormat, Unix timestamps, add*() and sub*() (including huge amounts), the helpers and the Carbon macros. A value outside the range throws InvalidDateException. Nothing returns a wrapped-around date, and no TypeError or ValueError escapes.
Amounts and timestamps
- An
addDays()orsubDays()amount (and hours, minutes, seconds) larger than the span of the whole supported calendar (about 3.7 million days, or the same span in hours, minutes or seconds) is refused up front withInvalidDateException. A smaller amount that lands outside the supported years is refused too. - A Unix timestamp must fall within Gregorian years 1 to 9999 (with a little room for the time zone). Anything further out is refused.
Hebrew::addMonths()andaddYears()take the same short time however large the amount is.
String-year thresholds
A string such as 1405/01/01 or 1405-01-01 passed to make() or a helper is read as a date of the calendar itself when the year is below the threshold. Otherwise it is read as a Gregorian string:
| Class | Own-calendar year | Otherwise |
|---|---|---|
Jalali / jdate() | below 1700 | Gregorian |
Hijri / hdate() | below 1700 | Gregorian |
Hebrew / hebrew_date() | 3000 or more | Gregorian |
The text must have exactly the shape Y/m/d or Y-m-d, with an optional time ( H:i , H:i:s or H:i:s.u after a space, T or t ) and an optional zone designator ( Z , +03:30 , +0330 or +03 , within ±14:00) that sets the time zone. Text that starts like a date of the calendar but has more (a zone name such as UTC , PM ) or less, a bare run of 3 to 8 digits, and a 5-digit year in Jalali or Hijri all throw InvalidDateException . Hebrew accepts years of 4 or 5 digits (up to 13759). A no-break space, ZWNJ, LRM and RLM count as spaces.
To pass a real Gregorian date below the threshold (for example the year 999), use a DateTimeImmutable. It is never reinterpreted. See the FAQ.
Umm al-Qura range
- The embedded Umm al-Qura month table covers AH 1300 to 1500 (1882-11-12 to 2077-11-16). Outside it, and always for
HijriVariant::Tabular,Hijriuses arithmetic rules that can differ from observation by a day or two.Hijri::hasUmmAlQuraData($year)tells you whether a year is covered. Years AH 1318 to 1500 are the ones checked against the official KACST calendar (Hijri::ummAlQuraVerifiedRange()). IranHolidaysuses official or reported dates for the Jalali years 1380 to 1405. For other years it reports Islamic holidays only inside the Umm al-Qura range. Outside it, and for years before the Hijri epoch, only the fixed Jalali holidays are returned, without an exception.all(),allTitles()andallFixed()work for every Jalali year from -620 to 9377.
Input size caps
| Where | Limit | When exceeded |
|---|---|---|
Validators (NationalCode, Sheba, BankCard, Mobile, PostalCode, VehiclePlate) | 4096 bytes per string | invalid Result, error input_too_long |
NumberToWords::convert() and fromWords() (string input) | 4096 bytes | InvalidNumberException, input_too_long |
Format string input (withSeparator()) | 4096 bytes | InvalidNumberException, input_too_long |
Format::withSeparator() and format_number() | 1000 characters in the plain decimal number (counting a leading -, the decimal point and leading zeros) | InvalidNumberException, input_too_long |
HolidayCalendar date or key given as a string | 64 bytes | InvalidDateException, input_too_long |
HolidayCalendar::withHoliday() title | 1 to 200 characters, valid UTF-8, no control characters | InvalidDateException, invalid_argument |
ArabicOptions negative word | 1 to 64 bytes, no spaces or control characters | InvalidNumberException, invalid_argument |
Slugify::make() separator | 64 bytes, valid UTF-8 | RtlyKitException (input_too_long or invalid_argument) |
format() pattern (Jalali, Hijri, Hebrew) | 256 bytes (MAX_FORMAT_LENGTH on each class) | InvalidDateException |
The caps are part of the contract (see API stability).
Number ranges
| Function | Range | Beyond it |
|---|---|---|
number_to_words($n) (Persian, default) | integers up to 21 digits (less than 10^21), and negatives | InvalidNumberException, number_too_large |
number_to_words($n, 'ar') and NumberToWords::convert($n, 'ar', $options) | integers less than 10^27, and negatives | InvalidNumberException, number_too_large |
NumberToWords::ordinal($n, 'ar') | 1 to 99 | InvalidNumberException (invalid_number for 0 or less, number_too_large above 99) |
number_to_words($n, 'de') or any other locale | only fa and ar | UnsupportedLocaleException |
NumberToWords::convert(), Format::ordinal() | whole numbers. Whole floats such as 3.0 are accepted | InvalidNumberException for 1.5, NaN, INF |
Format::ordinal() | non-negative integers | InvalidNumberException |
use function RtlyKit\number_to_words;
echo number_to_words(999999999, 'ar'), "\n";
// تسعمئة وتسعة وتسعون مليون وتسعمئة وتسعة وتسعون ألف وتسعمئة وتسعة وتسعون
// number_to_words(str_repeat('9', 28), 'ar') throws InvalidNumberException (number_too_large, limit "10^27 - 1")
// number_to_words(str_repeat('9', 22)) throws InvalidNumberException (number_too_large, limit "10^21 - 1")Setting ranges
| Setting | Range | Beyond it |
|---|---|---|
HolidayCalendar::withIslamicOffset() | -3 to +3 days | InvalidDateException |
HolidayCalendar::withHijriMonthStart() | within 3 days of the computed start. 29 or 30 days from a neighbouring month start you gave | InvalidDateException |
PrayerTimes::withTune() | -30 to +30 minutes, whole numbers, for fajr, sunrise, dhuhr, asr, maghrib, isha | InvalidPrayerConfigException |
new PrayerTimes() | Latitude -90 to 90, longitude -180 to 180, elevation -20000 to 20000 metres (negative counts as 0). No NaN or infinity | InvalidPrayerConfigException |
PrayerTimes::getTimes(), nextPrayer() | The local year of the date must be 1 to 9999 | InvalidDateException |
Data coverage
| Data | Coverage |
|---|---|
| Bank card BINs | 39 BINs. Others give null from getBankName() |
| Sheba bank codes | 38 codes. Others give null |
| National-code place of issue | 547 prefixes. Others give null |
| Official holiday dates | Jalali years 1394 and 1396 to 1405 (official), 1380 to 1393 and 1395 (reported, and the Imam Reza or Imam Hasan Askari day may be missing). Other years are estimated |
Prayer-time cities (PrayerTimes::forCity()) | 14: tehran, mashhad, isfahan, shiraz, tabriz, qom, mecca, medina, riyadh, istanbul, cairo, dubai, baghdad, jakarta. For any other place, use new PrayerTimes($lat, $lng, ...) |
| Prayer methods | Tehran, MWL, ISNA, Egypt, Makkah, Karachi. Asr factor 1 (standard) or 2 (Hanafi) |
| Prayer times at high latitudes | The default rule fills in a time the sun cannot produce. With HighLatitudeRule::None that time is null, not an error |
See Accuracy and data for what these tables are based on.
Platform limits
PHP 8.2 to 8.5 with no extension beyond a standard build, Laravel 11, 12 and 13, and Carbon 3. See API stability.
Was this page helpful?