Laravel Collection 日期比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33806518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:43:22  来源:igfitidea点击:

Laravel Collection Date comparison

phpsqldatelaravelphp-carbon

提问by Oskar Jedvert

Alright so I have been looking for hours for an answer but can't seem to find one. I have an array of "orders" all for different dates. I get all of the orders for this week, this should not be an issue, then I want to a tab for each day of the week.

好吧,所以我一直在寻找答案,但似乎找不到答案。我有一系列针对不同日期的“订单”。我收到了本周的所有订单,这应该不是问题,然后我想为一周中的每一天创建一个标签。

What I have tried so far is this:

到目前为止我尝试过的是:

$dinnerOrders->where('date','>',$date)->where('date','<', $date->endOfDay())->sortBy('created_at');

Where $date is :

$date 在哪里:

$dt = Carbon\Carbon::create()->startOfWeek();
Carbon\Carbon::setTestNow($dt);
$date = new Carbon\Carbon('this ' . $day);

And $dinnerOrders are get by:

$dinnerOrders 是通过以下方式获得的:

$dinnerOrders = collect([]);
foreach($restaurant->dinners as $dinner) {
    foreach($dinner->orders as $order) {
        $dinnerOrders[$order->id] = $order;
    }
 }

The dates seem correct and it words in sql. Is this not working because $dinnerOrders is a collection?

日期似乎是正确的,并且它是 sql 中的单词。这是不是因为 $dinnerOrders 是一个集合而不起作用?

What I'm getting is nothing, i.e an empty set, despite it working in mysql terminal.

我得到的是什么,即一个空集,尽管它在 mysql 终端中工作。

So what I'm asking is perhaps, can you do a date comparison on a collection? If so, how?

所以我要问的也许是,你能对一个集合进行日期比较吗?如果是这样,如何?

回答by patricus

As you state in your question, $dinnerOrdersis a Collection, not a query. The where()method on the Collectionworks a little differently.

正如您在问题中所述,$dinnerOrders是一个集合,而不是一个查询。工作where()方法Collection略有不同。

For Collections, the where()method does not accept an operator. It only does equality comparisons. The first parameter is the key, the second is the value, and the third is a boolean to flag a loose comparison (==) vs a strict comparison (===).

对于集合,该where()方法不接受运算符。它只进行相等比较。第一个参数是键,第二个是值,第三个参数是一个布尔值,用于标记松散比较 (==) 与严格比较 (===)。

What you're looking for is the filter()method. You pass in a Closure that does your date comparison. If the Closure returns true, the item stays in the Collection. If it returns false, the item is removed from the Collection. Something like this (just an example, the logic may need to be tweaked):

你要找的是filter()方法。您传入一个进行日期比较的闭包。如果 Closure 返回 true,则该项目保留在 Collection 中。如果返回 false,则从集合中删除该项目。像这样(只是一个例子,可能需要调整逻辑):

$dinnerOrders = $dinnerOrders->filter(function ($item) use ($date) {
    return (data_get($item, 'date') > $date) && (data_get($item, 'date') < $date->endOfDay());
});

Post Question Edit

发布问题 编辑

Based on the code provided in your edit, I'm guessing that a restaurant hasMany dinners, and a dinner hasMany orders. If this is correct, you can setup a relationship stating that a restaurant hasMany orders through dinners:

根据您的编辑中提供的代码,我猜餐厅有很多晚餐,晚餐有很多订单。如果这是正确的,您可以建立一个关系,说明餐厅通过晚餐有很多订单:

Restaurant.php:

餐厅.php:

public function orders() {
    // restaurant has many orders through dinners
    $this->hasManyThrough('App\Order', 'App\Dinner');
}

With this relationship setup, you could then get your information using the query builder:

通过这种关系设置,您可以使用查询构建器获取您的信息:

$dinnerOrders = $restaurant->orders()->where('date','>',$date)->where('date','<', $date->endOfDay())->get();