【问题标题】:How to filter resultset rows by comparing malformed date string and today's date?如何通过比较格式错误的日期字符串和今天的日期来过滤结果集行?
【发布时间】:2018-10-01 21:22:06
【问题描述】:

我的 mysql 数据库中有一个 VARCHAR 列,它用逗号而不是连字符存储日期。

我想通过将这些日期与当前日期进行比较来获取一些数据。为了获取当前日期,我使用 php5 方法 date("Y,m,d"); 并将其声明为 $date;

如果当前日期小于给定行的日期,那么我想检索它,否则从结果集中忽略它。

这是我的代码

$date=date("Y,m,d"); //current date to check if expiry date is valid or not
try {
    $conn = new PDO("mysql:host=******;dbname=******", $username, "******");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $query = "select id, discount, expirydate, description, logouploader from table WHERE expirydate>= ? LIMIT 10";
    $statement = $conn->prepare($query);
    $statement->execute(array($date));
    foreach($statement->fetchAll(PDO::FETCH_ASSOC) as $row) {
        echo $row['expirydate'];
    }  
}
catch(PDOException $e)
{
    echo "Connection failed: " . $e->getMessage();
}
$conn = null;

我的代码不比较日期;即使它应该留下小于$date;//当前日期的记录,它也会获取所有行

如何过滤我的结果集以仅返回尚未过期的行?

【问题讨论】:

  • 你服务器上日期的格式是什么
  • 我将其存储为 varchar,格式为 YYYYMMDD,例如 2018,04,15
  • 你的数据库中有逗号吗?
  • 是的,我的逗号与“Y,m,d”相同,例如 2018,04,27(示例)
  • 在使用date()之前尝试定义时区:php.net/manual/en/function.date-default-timezone-set.php

标签: php mysql date filtering date-formatting


【解决方案1】:

这是一个坏消息:您的代码正受到不良数据库设计的影响。如果您要存储日期值,请不要将它们存储在日期类型列之外的任何内容中。

这是个好消息:即使您不修复您的数据库结构(并且您确实应该),您也不需要任何 php 来让您的查询正常工作。事实上,您甚至不需要使用准备好的语句,因为没有要包含的变量。

代码:(SQLFiddle Demo)

SELECT discount,
       description,
       logouploader,
       DATE_FORMAT(STR_TO_DATE(expirydate, '%Y,%m,%d'), '%Y-%m-%d') AS `reformatted`
FROM `table`
WHERE STR_TO_DATE(expirydate, '%Y,%m,%d') >= CURDATE()
ORDER BY expirydate

这将产生所有尚未过期的折扣行(按日期排序)。

您可能会注意到:

  • 您无需在ORDER BY 子句中重新格式化expirydate,因为它被准确地排序为字符串。
  • 我可以很容易地调用 REPLACE() 而不是 STR_TO_DATE() 将逗号分隔的日期格式设置为连字符分隔的日期。
  • DATE_FORMAT() 将为您在结果集中格式化日期提供极大的灵活性,以便您的 php 可以做更少的处理。

【讨论】:

    【解决方案2】:

    使用 explode 将您的日期字符串转换为数组,然后重新组合您的日期字符串。

    function convertDateString($dateString){
    
      $dateArray = explode(',', $dateString);
    
      return date('Y-m-d', strtotime($dateArray[0] . '-' . $dateArray[1] . '-' . $dateArray[2]));
    
    }
    
    
    $date= date('Y-m-d'); //current date to check if expiry date is valid or not
    try {
    $conn = new PDO("mysql:host=******;dbname=******", $username, "******");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $query = "select id, discount, expirydate, description, logouploader from table WHERE expirydate>= ? LIMIT 10";
    $statement = $conn->prepare($query);
    $statement->execute(array($date));
    foreach($statement->fetchAll(PDO::FETCH_ASSOC) as $row) {
    
      if(strtotime($date) < strtotime(convertDateString($row['expirydate']))){
    
        echo $row['expirydate'];
    
    
      }else {
    
        //Do something else;
    
      }
    
    
    }
    
    }
    catch(PDOException $e)
        {
            echo "Connection failed: " . $e->getMessage();
        }
        $conn = null;
    

    【讨论】:

    • 这是什么原因?我的数据库中有这样的日期 0000,00,00。 0000-00-00 是否将其与 0000,00,00 进行比较?
    • YYYY,MM,DD 不是有效的日期格式。 YYYY-MM-DD 是有效的日期格式。因此,我们将您的日期字符串切掉并将其改造成正确的字符串。然后我们将日期字符串转换为时间戳并比较值。
    • @haider 请注意,我还将您的 $date 变量的格式更改为 'Y-m-d'
    • 它工作得很好,谢谢你,但是先生,我的公司在他们的数据库中有 22000 个数据,你在获取后比较它。问题是它会影响网站的速度,我需要在获取之前解决这个问题。有什么解决办法吗?我是刚毕业后才开始工作的新人,我完全受够了。
    • 我不是优化代码和执行所需处理步骤数量的专家。但如果我站在你的立场上,我会编写一个查询,将你当前的日期放在数据库中,并用它们的 DateTime 等效值替换它们。然后您可以形成一个查询,该查询将返回您想要的结果。如果我解决了您的问题,请标记为已接受的答案。干杯
    猜你喜欢
    • 2014-09-09
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2015-11-24
    相关资源
    最近更新 更多