奇怪的Usort行为


Weird Usort behavior

我创建了一个包含多个对象的数组,这些对象有一个startTime和一个endTime。首先我需要最低的startTime,然后是最高的endTime

array{
   [1541] =>  object(task)#430 (2){ ["startTime"]=> string(19) "2016-03-24 06:29:35" ["endTime"]=> string(19) "2016-03-24 06:31:35"}
   [1545] =>  object(task)#431 (2){ ["startTime"]=> string(19) "2016-03-24 07:20:50" ["endTime"]=> string(19) "2016-03-24 07:25:50"}
}

因此,在本例中,最低的startTime为"2016-03-24 07:25:50",最高的endTime为"2016 03-24 07:05:50"。但奇怪的是,这并不是(总是)我得到的结果(5次中有3次)

the result is lowest startTime is "2016-03-24 07:25:50" and the highest endTime is "2016-03-24 06:29:35"

我使用基于startTime属性的usort对这些对象进行排序。这是我使用的代码

class StaticsComponent extends CComponent  {
    public static  function cmp_start($a, $b) {
        if (microtime($a->startTime) == microtime($b->startTime)) {
           return 0;
        }
        return (microtime($a->startTime) > microtime($b->startTime)) ? -1 : 1;
    }
    public static  function cmp_end($a, $b) {
        if (microtime($a->startTime) == microtime($b->startTime)) {
           return 0;
        }
        return (microtime($a->startTime) < microtime($b->startTime)) ? -1 : 1;
    }
}
class OrderBcStats extends Orderbc {
    public $tasks;
    public $startTime;
    public $endTime;
    public function process(){
        if(empty($this->tasks)){
           return;
        }
        $starts = $this->tasks;
        $ends = $this->tasks;
        usort($starts, array('StaticsComponent','cmp_start'));
        usort($ends, array('StaticsComponent','cmp_end'));
        $first = reset($starts);
        $last = end($ends);
        $this->startTime = $first->startTime;
        $this->endTime = $last->endTime;
    }
}

附加信息:这是一个Yii项目,PHP版本5.4.40,OS Centos,apache 2.0

根据文档"microtime()返回当前Unix时间戳(以微秒为单位)"(增加强调)。它所使用的唯一参数是布尔值$get_as_float。因此,您不是根据项目的时间进行排序,而是根据(大致)它们的顺序进行排序。

您可以创建DateTime对象并比较它们的时间戳。然而,如果你对格式有把握,那么你可以利用这样一个事实,即对于ISO格式的日期,字母顺序和日期顺序是一样的。。。

所以我想不是

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

你想要这样的东西吗

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

或者

$a_time = new DateTime($a->startTime);
$b_time = new DateTime($a);
if ($a_time == $b_time) {
   return 0;
}
return ($a_time > $b_time) ? -1 : 1;   

警告:未经测试,但应能正常工作。