usort On String to Date Converted
Asked Answered
P

2

0

I'm trying to take a string in the format of mdY H:i and sort it in an array. My code for the sort is:

    function orderDates($items) {
    //Sort them. Latest one first
    usort($items, function ($a, $b) {
        $a = date('dmY H:i', strtotime($a));
        $b = date('dmY H:i', strtotime($b));

        if ($a == $b) {
            return 0;
        }
        return ($a > $b) ? -1 : 1;
    });

    return $items;
}

I have a test case of:

public function test_orderDates() {
    $items = ["09082020 00:00", "12072020 00:00", "14062020 00:00", "17052020 00:00", "21062020 00:00", "24052020 00:00", "26072020 00:00"];

    $rv = $this->cleanupFolder->orderDates($items);

    $this->assertNotNull($rv);
    $this->assertEquals(7, sizeOf($rv));

    $this->assertEquals("09082020 00:00", $rv[0]);
    $this->assertEquals("26072020 00:00", $rv[1]);
    $this->assertEquals("12072020 00:00", $rv[2]);
    $this->assertEquals("21062020 00:00", $rv[3]);
    $this->assertEquals("14062020 00:00", $rv[4]);
    $this->assertEquals("24052020 00:00", $rv[5]);
    $this->assertEquals("17052020 00:00", $rv[6]);
}

I expect it to be in that order but it just comes back in the same order. I don't understand what I've done wrong.

Perfusion answered 19/8, 2020 at 8:10 Comment(3)
You try to compare string, keep the unix time value and convert it to a string only after.Toritorie
I don't have the unix time value. I have a string which is in the format of dmY. That needs to change to a unix time value before I can compare itPerfusion
EDIT: @JérémyCasper I get you now. You are correct!Perfusion
B
1

Look carefully at the string $a = date('dmY H:i', strtotime($a));

strtotime($a) is trying to convert a string to a timestamp. Because you have a custom date format, the string 09082020 00:00 will be converted to false.

After that, date('dmY H:i', false) will return 01011970 00:00. This why the sorting doesn't work.

I'll suggest using DateTime::createFromFormat.

    usort($items, function ($a, $b) {
        $a = DateTime::createFromFormat('dmY H:i', $a);
        $b = DateTime::createFromFormat('dmY H:i', $b);

        if ($a == $b) {
            return 0;
        }
        return ($a > $b) ? -1 : 1;
    });
Biaxial answered 19/8, 2020 at 8:26 Comment(0)
S
1

In this part

date('dmY H:i', strtotime($a));

you are trying to create date with format but you set value with strtotime() which returns Unix timestamp (int). So you are probably looking for something like:

\DateTime::createFromFormat('dmY H:i', $a);

So it could be something like:

function orderDates($items) {
    //Sort them. Latest one first
    usort($items, function ($a, $b) {
        $a = \DateTime::createFromFormat('dmY H:i', $a);
        $b = \DateTime::createFromFormat('dmY H:i', $b);

        if ($a == $b) {
            return 0;
        }
        return ($a > $b) ? -1 : 1;
    });

    return $items;
}
Sable answered 19/8, 2020 at 8:24 Comment(0)
B
1

Look carefully at the string $a = date('dmY H:i', strtotime($a));

strtotime($a) is trying to convert a string to a timestamp. Because you have a custom date format, the string 09082020 00:00 will be converted to false.

After that, date('dmY H:i', false) will return 01011970 00:00. This why the sorting doesn't work.

I'll suggest using DateTime::createFromFormat.

    usort($items, function ($a, $b) {
        $a = DateTime::createFromFormat('dmY H:i', $a);
        $b = DateTime::createFromFormat('dmY H:i', $b);

        if ($a == $b) {
            return 0;
        }
        return ($a > $b) ? -1 : 1;
    });
Biaxial answered 19/8, 2020 at 8:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.