0

I use several date functions with dates around the French republic of 1792-1806.

But I want to know if the (php8) date function can handle these dates.

function CheckFrDate($CheckDate){
  $BeginFrDate = date_create_from_format('d/m/Y', '22/09/1792');
  $EndFrDate = date_create_from_format('d/m/Y', '22/09/1806');
  if (
    $CheckDate->getTimestamp() > $BeginFrDate->getTimestamp() && 
    $CheckDate->getTimestamp() < $EndFrDate->getTimestamp()){
    return 1;
  }else{
    return -1;  
  } 
}

So a date like 23/09/1793 should be ok. But my function keeps returning false.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • 2
    Works for me. https://3v4l.org/ZkSlZ Are you using a very old and 32-bit version of PHP? – Sammitch Aug 02 '23 at 18:23
  • FYI: please also see this answer: https://stackoverflow.com/a/10450710/367456 and then especially the last lines, but for France IIRC this could be of interest. – hakre Aug 03 '23 at 19:45
  • Your function never returns false, it returns either 1 or -1, both of which evaluate to boolean true. I suggest you check the logic around how you are using this function, and also return proper boolean values. PHP works fine with nearly any date you can think of. – miken32 Aug 03 '23 at 20:34

2 Answers2

0

If a date function returns false, you are able to get the real (verbose) error message by calling var_dump(date_get_last_errors());

read more: https://www.php.net/manual/en/function.date-get-last-errors.php

  • I think that by: _"But my function keeps returning false."_, the return value -1 is meant, and not a real "false" value. Note the warning on [this page](https://www.php.net/manual/en/language.types.boolean.php): _"**Warning** -1 is considered **true**, like any other non-zero (whether negative or positive) number!"_ – KIKO Software Aug 02 '23 at 18:41
  • Documentation says the return type is `DateTime|false` so `-1` is not valid as return type. – Nils Langner Aug 02 '23 at 18:45
  • 1
    I agree the question is confusing, but nowhere does it say that _a date function_ returns false. I don't think any real attempt to debug has been done. – KIKO Software Aug 02 '23 at 18:47
0

I'd dare say that PHP date ranges do not have hard-coded limits, probably just the integer size or some similar platform limit. However, not all input mechanisms work the same way. For example:

$years = [
    -25000,
    0,
    9999,
    10000,
    25000,
];
foreach ($years as $year) {
    $dt1 = date_create_from_format('d/m/Y', "22/09/$year");
    $dt2 = new \DateTime();
    $dt2->setDate($year, 9, 22);
    var_dump($year, $dt1, $dt2);
    echo "\n";
}
int(-25000)
bool(false)
object(DateTime)#1 (3) {
  ["date"]=>
  string(28) "-25000-09-22 16:16:09.918321"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}

int(0)
object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "0000-09-22 16:16:09.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}
object(DateTime)#3 (3) {
  ["date"]=>
  string(26) "0000-09-22 16:16:09.918367"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}

int(9999)
object(DateTime)#1 (3) {
  ["date"]=>
  string(26) "9999-09-22 16:16:09.000000"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}
object(DateTime)#2 (3) {
  ["date"]=>
  string(26) "9999-09-22 16:16:09.918415"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}

int(10000)
bool(false)
object(DateTime)#1 (3) {
  ["date"]=>
  string(27) "10000-09-22 16:16:09.918451"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}

int(25000)
bool(false)
object(DateTime)#2 (3) {
  ["date"]=>
  string(27) "25000-09-22 16:16:09.918476"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
}

In particular, date_create_from_format() reports this:

date_create_from_format('d/m/Y', "22/09/25000");
print_r(DateTime::getLastErrors());
Array
(
    [warning_count] => 0
    [warnings] => Array
        (
        )

    [error_count] => 1
    [errors] => Array
        (
            [10] => Trailing data
        )

)

This happens because, as documented, Y format code is:

A full numeric representation of a year, up to 4 digits

Regarding your specific code, it appears to work as expected:

function CheckFrDate($CheckDate){
    $BeginFrDate = date_create_from_format('d/m/Y', '22/09/1792');
    $EndFrDate = date_create_from_format('d/m/Y', '22/09/1806');
    if (
        $CheckDate->getTimestamp() > $BeginFrDate->getTimestamp() &&
        $CheckDate->getTimestamp() < $EndFrDate->getTimestamp()){
        return 1;
    }else{
        return -1;
    }
}

$CheckDate = date_create_from_format('d/m/Y', '23/09/1793');
var_dump(CheckFrDate($CheckDate));
int(1)

I no longer have a 32-bit Windows system to test but, if I recall correctly, \DateTime interface was never affected by the 1970 Unix Epoch limit. However, if you use ->getTimestamp() to obtain a Unix timestamp, you'll get an integer that will be.

You can drop Unix time altogether:

function CheckFrDate($CheckDate)
{
    $BeginFrDate = date_create_from_format('d/m/Y', '22/09/1792');
    $EndFrDate = date_create_from_format('d/m/Y', '22/09/1806');
    if ($CheckDate > $BeginFrDate && $CheckDate < $EndFrDate) {
        return 1;
    } else {
        return -1;
    }
}
Álvaro González
  • 142,137
  • 41
  • 261
  • 360