DateTimeは時間文字列の解析に失敗しました

2020-05-23 php datetime datetime-format

JSONから引き継がれた配列のアイテムごとに2つの日付と時刻の文字列を渡します。

これらの日付は配列に正常に格納されていますが、 DateTime関数は何らかの理由でそれらを好きではありません。

私はさまざまな形式を使用してみましたが、日付だけ、時間だけですが、何もうまくいきませんでした。

使用しているJSONファイルとPHPテストファイルを提供しました。

<?php 
    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    $revokes = jsonDecode(file_get_contents("../revokes.json"), true);

    $certificates = $revokes['certificates'];

    // Prints the revokes array
    // print_r($revokes);

    $dates = array();

    foreach ($certificates as $certificate_key => $certificate) {
        $signed = $certificate['signed'];
        $revoked = $certificate['revoked'];
        $dates[] = array(
            "signed" => $signed,
            "revoked" => $revoked
        );
    }

    // Prints the dates
    // print_r($dates);

    $intervals = array();
    foreach ($dates as $key) {

        $newTimeAdd = new DateTime($key["signed"]);
        $newTimeRead = new DateTime($key["revoked"]);
        $interval = $newTimeAdd->diff($newTimeRead);

        // returns 0 on all elements of the interval array.
        // var_dump($interval);

        $intervals[] = $interval->days;//get days
    }
    if(!empty($intervals)) {
        $average = average($intervals);
    }

    // Prints nothing
    // print_r($intervals); 


    function average($arr) {
        return array_sum($arr)/count($arr);
    }


    function jsonDecode($json, $assoc = false)
    {
        $ret = json_decode($json, $assoc);
        if ($error = json_last_error())
        {
            $errorReference = [
                JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded.',
                JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON.',
                JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded.',
                JSON_ERROR_SYNTAX => 'Syntax error.',
                JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded.',
                JSON_ERROR_RECURSION => 'One or more recursive references in the value to be encoded.',
                JSON_ERROR_INF_OR_NAN => 'One or more NAN or INF values in the value to be encoded.',
                JSON_ERROR_UNSUPPORTED_TYPE => 'A value of a type that cannot be encoded was given.',
            ];
            $errStr = isset($errorReference[$error]) ? $errorReference[$error] : "Unknown error ($error)";
            throw new \Exception("JSON decode error ($error): $errStr");
        }
        return $ret;
    }
?>
{
    "lifeExp": "2 Days",
    "certificates": [
        {
            "name": "CCS Group Pte Ltd",
            "signed": "22/05/2020 10:31:00",
            "revoked": "23/05/2020 5:40:00",
            "files": {
                "p12": "certificates/:id/certificate.p12",
                "pem": "certificates/:id/certificate.pem",
                "key": "certificates/:id/certificate.key",
                "password": "certificates/:id/certificate.password"
            }
        },
        {
            "name": "Hoola Inc",
            "signed": "16/05/2020 12:40:00",
            "revoked": "19/05/2020 04:00:00",
            "files": {
                "p12": "certificates/:id/certificate.p12",
                "pem": "certificates/:id/certificate.pem",
                "key": "certificates/:id/certificate.key",
                "password": "certificates/:id/certificate.password"
            }
        }
    ]
}

Answers

日付形式はヨーロッパ形式(DD / MM / YYYY)です。つまり、 DateTime::createFromFormat()を使用して正しい形式を指定し、 DateTimeで正しく処理されるようにする必要があります。これは、NNP / NN / NNNNの日付形式を表示するときにP HPが米国の日付形式を想定しているためです

<?php

$json = json_decode('{
    "lifeExp": "2 Days",
    "certificates": [
        {
            "name": "CCS Group Pte Ltd",
            "signed": "22/05/2020 10:31:00",
            "revoked": "23/05/2020 5:40:00",
            "files": {
                "p12": "certificates/:id/certificate.p12",
                "pem": "certificates/:id/certificate.pem",
                "key": "certificates/:id/certificate.key",
                "password": "certificates/:id/certificate.password"
            }
        },
        {
            "name": "Hoola Inc",
            "signed": "16/05/2020 12:40:00",
            "revoked": "19/05/2020 04:00:00",
            "files": {
                "p12": "certificates/:id/certificate.p12",
                "pem": "certificates/:id/certificate.pem",
                "key": "certificates/:id/certificate.key",
                "password": "certificates/:id/certificate.password"
            }
        }
    ]
}', true);

$signed = $json['certificates'][1]['signed'];
$revoked = $json['certificates'][1]['revoked'];

$newTimeAdd  = DateTime::createFromFormat('d/m/Y H:i:s', $signed);
$newTimeRead = DateTime::createFromFormat('d/m/Y H:i:s', $revoked);
$interval    = $newTimeAdd->diff($newTimeRead);
echo $interval->days;

出力

2

デモ

Related