【问题标题】:Laravel Eloquent compare date from datetime fieldLaravel Eloquent 比较日期时间字段中的日期
【发布时间】:2014-09-28 04:22:23
【问题描述】:

我想通过一个表达式从一个表中获取所有的行:

table.date <= 2014-07-10

但如果该列包含日期时间,我们就说:

2014-07-10 12:00:00

但如果我这样做:

where('date', '<=', $date)

它不会得到该行。

我猜这是因为 $date = 2014-07-10 这使得 MySQL 假设它是 2014-07-10 00:00:00。

在常规 MySQL 中我会这样做

where DATE(date) <= $date

使用 Laravel 的 Eloquent 的等价物是什么?

【问题讨论】:

    标签: php mysql datetime laravel-4


    【解决方案1】:

    如果您仍然想知道如何解决它。

    我用

    protected $dates = ['created_at', 'updated_at', 'aired'];

    在我的模型和我做的地方

    where('aired', '&gt;=', time());

    所以只需使用 unix 在哪里进行比较。

    另一方面,在视图中,您必须使用日期对象。

    【讨论】:

    • 这是唯一对我有用的,因为我已经在 $dates 中定义了 :) 谢谢
    • @pixie_frigo 文档中的 $protected $dates 在哪里?
    【解决方案2】:

    这是我的逻辑: 如果您正在比较日期,那么您的方法应该是 whereDate,如果您比较完整的日期时间,那么您的方法将只在哪里:

    $calendar_alert = DB::table('calendar_alerts')->whereDate('when', '=', now()->format('Y-m-d'))->where('when', '>', now()->format('H:i:s'))->get();
    

    【讨论】:

      【解决方案3】:

      您可以通过选择以下一种语法来获取日期“2016-07-14”或“2016-07-14”之前的所有记录:

      ->whereDate('date','=','2014-07-10')
      
      ->whereDate('date', '<=', '2014-07-10')
      

      或者使用其他代码来获取动态日期

      whereDate('date',$date)
      

      【讨论】:

      • 这似乎根本无法回答问题。
      • @SteveFromAccounting 在这种情况下,代码不适用于 Laravel 吗?可以发一下代码sn-ps吗?
      【解决方案4】:
      use Carbon\Carbon;
      
      public function scopePublished($query)
      {
        $now = Carbon::now();
        $date = Carbon::parse($now)->toDateString();
        $time = Carbon::parse($now)->toTimeString();
        return $query->whereDate('published_at', '<', $date)
        ->orWhere(function($query) use ($date, $time) {
          $query->whereDate('published_at', '=', $date)
          ->whereTime('published_at', '<=', $time);
        });
      }
      

      【讨论】:

        【解决方案5】:

        您是否考虑过使用:

        where('date', '<', '2014-08-11')
        

        您应该避免在 MySQL 中的索引列上使用 DATE() 函数,因为这会阻止引擎使用索引。

        更新

        由于似乎对DATE() 和索引的重要性存在一些分歧,我创建了一个fiddle 来展示差异,请参阅POSSIBLE KEYS

        【讨论】:

        • 为什么他应该避免在索引列上使用DATE()
        • 这可能是一个解决方案,但看起来更像是一种 hack,而不是最佳实践。如果一个文件中包含 00:00:00 作为时间呢?
        • @almo,一旦你习惯了 MySQL 比较日期的方式,它就不会太糟糕了。这就像字符串比较; “2014-08-10 00:00:00”大于“2014-08-10”。
        • @Almo 你应该避免在索引列上使用 DATE() 因为它会阻止 MySQL 使用这个索引。如果可能,请使用比较运算符右侧的表达式。不,这是最佳实践,而不是 hack!
        • ::whereRaw("DATE(date) &lt;= '2014-08-10'")。 @Arth他没有提到索引,所以我不知道它有什么毛病。正如你所说,@almo 2014-07-10 将被转换为 DATETIME (2014-07-10 00:00:00)。但是,您将DATEDATETIME 进行比较,您要么将DATETIME 转换为DATE,要么将23:59:59 添加到$date
        【解决方案6】:

        Laravel 4+ 为您提供这些方法:whereDay()whereMonth()whereYear() (#3946) 和 whereDate() (#6879)。

        他们为您执行 SQL DATE() 工作,并管理 SQLite 的差异。

        你的结果可以这样实现:

        ->whereDate('date', '<=', '2014-07-10')
        

        有关更多示例,请参阅#3946 的第一条消息和此Laravel Daily article


        更新: 虽然上述方法很方便,但正如 Arth 所说,它在大型数据集上效率低下,因为必须对每条记录应用 DATE() SQL 函数,从而丢弃可能的索引。

        以下是一些进行比较的方法(但请阅读下面的注释):

        ->where('date', '<=', '2014-07-10 23:59:59')
        
        ->where('date', '<', '2014-07-11')
        
        // '2014-07-11'
        $dayAfter = (new DateTime('2014-07-10'))->modify('+1 day')->format('Y-m-d');
        
        ->where('date', '<', $dayAfter)
        

        注意事项:

        • 23:59:59 可以(暂时)因为 1 秒的精度,但请看这篇文章:23:59:59 is not the end of the day. No, really!
        • 请记住“零日期”情况(“0000-00-00 00:00:00”)。尽管应该避免这些“零日期”,但它们是许多问题的根源。如果需要,最好使该字段可以为空。

        【讨论】:

        • 同样,我建议不要使用这种方法,它会将列包装在 DATE() 函数中,并且引擎无法在列上使用索引。
        • 没问题!我对日期像字符串一样进行比较是错误的,它们只是被转换然后比较。 2014-07-11 将在比较之前隐式转换为 2014-07-11 00:00:00,幸运的是,这与您的其他解释很好。
        • 另外请注意,您可以愉快地使用WHERE date &lt; :date + INTERVAL 1 DAY,而不是在 PHP 中乱搞日期
        • 确实是关于 MySQL INTERVAL。不过,如果可能的话,我更喜欢在 PHP 端进行处理,而不是 MySQL 甚至 Apache。我厌倦了他们所有的微妙之处。
        • THAX ALOT:对我有用的地方我正在使用 laravel 7+
        【解决方案7】:

        你可以用这个

        whereDate('date', '=', $date)
        

        如果您提供 whereDate 则仅比较日期时间字段中的日期。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-12-16
          • 2015-12-01
          • 2013-10-28
          • 2012-01-20
          • 2015-07-20
          • 1970-01-01
          • 2010-11-06
          • 2016-09-19
          相关资源
          最近更新 更多