【问题标题】:Symfony - search table by month, year for datetime fieldsSymfony - 按月,年搜索日期时间字段的表格
【发布时间】:2011-01-25 14:49:28
【问题描述】:

我正在尝试在前端模块上创建一个搜索过滤器,它将按 2 个字段进行过滤,分别是月和年

我的数据库表中有项目,它们有一个日期时间字段。

我希望能够创建一个搜索,如果我从 2 个下拉菜单中选择 1 月和 2010 年,那么所有具有日期时间的项目都像:

2010-01-24 10:50:52

2010-01-25 10:50:52

将被列出

我正在使用 symfony 1.4 和 Propel ORM

谢谢

【问题讨论】:

    标签: symfony1 propel symfony-1.4


    【解决方案1】:

    为什么不尝试创建 2 个日期并检查该日期是否在它们之间,例如 (2010-01-01 >= $date && 2010-01-31

    如果您绝对必须检查月份和年份,我建议使用 YEAR(date) = $yourDate 和 Month(date) = $yourMonth 等函数,此函数应符合 CUSTOM 标准,如下所示:

    $criterias->addCriteria(TablePeer::DATE_ATTRIBUTE,"YEAR(". TablePeer::DATE_ATTRIBUTE .") = $year",Criteria::CUSTOM);
    $criterias->addCriteria(TablePeer::DATE_ATTRIBUTE,"MONTH(". TablePeer::DATE_ATTRIBUTE .") = $month",Criteria::CUSTOM);
    

    这是MysqlDateFunctions的链接

    【讨论】:

    • 我同意。还有其他方法可以执行此操作,但这应该是最有效的。取用户提供的月份和年份。在时间 00:00:00 计算该月的第一天,在时间 23:59:59 计算该月的最后一天。这将允许非常有效的搜索。像 MONTH、YEAR 等数据库转换会消耗资源并且经常绕过索引。
    • 如果我想按月和年搜索呢?
    • 在这种情况下,我会使用 YEAR() 和 MONTH() 函数,但仅在绝对必要时使用。日期操作是一项相当昂贵的操作。
    • 是在自定义查询中还是我可以将它们传递给条件对象?
    • 一定是CUSTOM,不知道有没有等价的推进器。但是使用自定义应该可以很好地工作
    【解决方案2】:

    我在一个应用中有一些非常相似的东西。我将sfFormExtraPlugin 用于花哨的日期小部件。

    我的模型是“投诉”,我的操作是“探索”。

    lib/form/ExploreForm.php

    class ExploreForm extends BaseForm
    {
      public function configure()
      {
    
        $this->setWidgets
          (array(
                 'explore_range' => new sfWidgetFormDateRange
                 (array(
                        'from_date'   => new sfWidgetFormJQueryDate(),
                        'to_date'   =>  new sfWidgetFormJQueryDate(),
                        'label'   =>  'Date of Service ranging ',
                        )
                  )
                 )
           );
    
        $this->setValidators(array(
                                   'explore_range'       => new sfValidatorDateRange
                                   (array(
                                          'required' => true,
                                          'from_date' => new sfValidatorDate(array('required' => false)),
                                          'to_date' => new sfValidatorDate(array('required' => false))
                                          )),
                                   'from'   =>  new sfValidatorPass(),
                                   'to'   =>  new sfValidatorPass()
                                   )
                             );
    
      }
    }
    

    apps/frontend/modules/complaint/templates/exploreSuccess.php

    <form action="<?php echo url_for('complaint/explore') ?>" method="GET">
      <input type="submit" value="Change date range" style="float:right" />
      <ul>
    <?php echo $form->renderUsing('list')  ?>
      </ul>
    </form>
    

    apps/frontend/modules/complaint/actions/actions.class.php 中: 公共函数执行探索($请求) { // 默认值:本月的第一天 - 1 年

      $this->form = new ExploreForm(array(
                    'explore_range'   =>  array (
                                 'from'   =>  $a_year_ago,
                                 'to'   =>  $last_of_last_month
                                 )
                      ));
    
      if ($request->hasParameter('explore_range') ) {
    $this->form->bind( array('explore_range' => $request->getParameter('explore_range')) );
    $this->logMessage("bound", "debug");
    if ($this->form->isValid()) {
      $this->form_values = $this->form->getValues(); # cleaned
      $this->logMessage("validation WIN", "debug");
    }
    else {
      $this->logMessage("validation FAIL", "debug");
      $this->form_values = $this->form->getDefaults();
    }
    
      }
      else {
    $this->logMessage("no explore_range param", "debug");
    $this->form_values = $this->form->getDefaults();
      }
    
      $this->from = $this->form_values['explore_range']['from'];
      $this->to = $this->form_values['explore_range']['to'];
    
    
      /* complaints per month */
      $this->complaints_by_month = ComplaintTable::getMonthCounts($this->from, $this->to);
    
    
      // ...
    
    }
    

    而实际查询在模型中,lib/model/doctrine/ComplaintTable.class.php

    public static function getMonthCounts($from, $to) {
    
      $connection = Doctrine_Manager::connection();
      $query = <<<ENDSQL
        SELECT year(`date`) as y, month(`date`) as m, count(*) as c
        FROM `complaints`.`complaint`
        WHERE `date` BETWEEN ? AND ?
        GROUP BY year(`date`), month(`date`)
    ENDSQL;
    
      $statement = $connection->execute($query, array($from, $to));
    
      $result = array();
      while ($row = $statement->fetch()) {
        $result[ sprintf("%04d-%02d",$row[0], $row[1]) ] = $row[2];
      }
    
      return self::addZeroRows($result, $from, $to);
    }
    
    public static function addZeroRows($set, $from, $to) {
      /* insert zero counts for months with no count */
      $from_fields = date_parse($from);
      $to_fields = date_parse($to);
      $start_y = $from_fields['year'];
      $end_y = $to_fields['year'];
      $start_m = $from_fields['month'];
      $end_m = $to_fields['month'];
    
      $i = 0;
      for ( $y = $start_y;  $y <= $end_y;  $y++ ) {
        for (   $m = ($y == $start_y ? $start_m : 1) ;
                ($y == $end_y && $m <= $end_m) || ($y < $end_y && $m <= 12);
                $m++
                ) {
          $y_m = sprintf("%04d-%02d",$y,$m);
          if ( !isset( $set[$y_m] ) ) {
            $set[$y_m] = 0;
          }
          if ($i++ > 100) {  // don't infinitely loop... you did it wrong
            return $set;
          }
        }
      }
    
    
      ksort($set);
      return $set;
    }
    

    现在,我正在使用 Doctrine,因此您必须在模型部分中将其翻译成 Propelese,而且您可能不会做我在这里做的“按月细分的统计数据”,但是它应该可以帮助您继续前进。祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-11
      • 2023-03-28
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      相关资源
      最近更新 更多