计算 DATETIME 与 php 之间的时间

Calculating time between DATETIME with php

我正在从一个简单的 SELECT 查询中调用一些数据,其中该行包含三个字段,start_time(DATETIME)end_time(DATETIME)reopen_time(DATETIME)

我正在尝试计算 start_timeend_time 之间的时间以及 start_timereopen_time 之间的时间(如果是这种情况的话)。我要确定的方法是通过另一个名为 complete 的列,它将值设置为 1 或 0。它将计算 start_timeend_time 如果完整值为 1 并且start_timereopen_time 的值为 0。

现在,我的 PHP 到目前为止看起来像下面这样;我正在找人帮忙装箱子和眼睛:

$id=$_GET['id']; //this grabs the id from the previous page depending on which task is clicked.
$sql = "SELECT * FROM to_do_list WHERE id=$id";
$result = mysqli_query($db, $sql);

if(mysqli_num_rows($result) > 0){
    while($row = mysqli_fetch_assoc($result)){    
        $date1 = $row["start_time"];        
        $date2 = $row["end_time"];            
        $diff = abs(strtotime($date2) - strtotime($date1));            
        $years = floor($diff / (365*60*60*24));
        $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
        $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));            
        printf("%d years, %d months, %d days\n", $years, $months, $days);            
    }
} else {
    echo "There are no tasks!";
}

现在,我得到的结果是:0 年,0 个月,0 天,但没有错误。我假设数据库中的数据格式可能不正确?

我会花一些时间(看到双关语了吗?)看看 PHP Class DateTime (http://php.net/manual/en/class.datetime.php)。

这个 class 已经有一个内置的方法来计算日期之间的差异,包括闰年等情况,创建一个 DataInterval 对象。然后使用 DataInterval 对象,您可以格式化和拉出您想要的部分(月、日、年等...)

while($row = mysqli_fetch_assoc($result)){    
    $date1 = $row["start_time"];        
    $date2 = $row["end_time"];    
    $datetime1 = new DateTime($date1);
    $datetime2 = new DateTime($date2);
    $interval = $datetime1->diff($datetime2);
    echo $interval->format('%y years, %m months, %d days');     
 }

注意:如果 $date1$date2 字段完全相同,您将得到和间隔报告 0 的月份、年份等...因为没有时间差异。

此外,请注意,因为 DateInterval 考虑了闰年等变化,您需要记住并非每个 'month' 都是相等的。如果您需要知道确切的天差,DateInterval 提供 public 属性 days:

 $date1 = new DateTime('2015-02-27');  // 2015 was a 'regular' year, Feb had 28 days
 $date2 = new DateTime('2015-03-27');
 $interval_1_2 = $date1->diff($date2);

 $date3 = new DateTime('2016-02-27'); // 2016 was a 'leap' year, Feb had 29 days
 $date4 = new DateTime('2016-03-27');
 $interval_3_4 = $date3->diff($date4);

 echo $interval_1_2->format('%m months, %d day '); // 1 month 0 days 
 echo "Total Days: ".$interval_1_2->days."\n"; // 28 days

 echo $interval_3_4->format('%m months, %d day');  // 1 month 0 days
 echo "Total Days: ".$interval_3_4->days."\n"; // 29 days

Dev-club 的第一条规则:不要重新发明轮子,除非:

  1. 您不关心功能,只是在尝试解决很多很多次之前已解决的问题,以进行某种学习实验。
  2. 并愿意最终得到一个不完全涵盖 100% 用例的古怪结果。
  3. 只是玩得开心。

您实际上可以在 mysql 中使用 TIMESTAMPDIFF

直接执行此操作
$id= filter_input(INPUT_GET, 'id',FILTER_VALIDATE_INT); 
//crude sql injection filter, dont use in production

$sql = "
    SELECT *,
    TIMESTAMPDIFF(YEAR, start_time , end_time) as years,
    TIMESTAMPDIFF(MONTH, start_time , end_time) as months,
    TIMESTAMPDIFF(DAY, start_time , end_time) as days
    FROM to_do_list WHERE id=$id
";

$result = mysqli_query($db, $sql);

if(mysqli_num_rows($result) > 0){
    while($row = mysqli_fetch_assoc($result)){    
        $date1 = $row["start_time"];        
        $date2 = $row["end_time"];            
        $years = $row["years"];        
        $months = $row["months"];        
        $days = $row["days"];        

        printf("%d years, %d months, %d days\n", $years, $months, $days);            
    }
} else {
    echo "There are no tasks!";
}

请参阅此 answer 以获取有关如何正确处理 sql 注入预防的信息