我正在为一个钢琴调谐器的客户编写一个时间记录程序,我已经编写了以下PHP代码来给一个记录一个状态“to do”:

$last_tuned = '2017-01-05';
$tuning_period = 3;

$month_last_tuned = date('Y-m', strtotime(date('Y-m-d', strtotime($last_tuned))));

$next_tuning = date('Y-m', strtotime($month_last_tuned.(' +'.$tuning_period.' months')));

if (time() > strtotime($next_tuning.' -1 months')) {
    if (time() > strtotime($next_tuning)) {
        return 'late';
    } else {
        return 'upcoming';
    }
}

如您所见,$last_tuned变量采用日期(YYYY-MM-DD)格式。然后将其转换为(YYYY-MM)格式。
一旦转换,一个与$tuning_period相同的额外月数将被添加到$month_last_tuned变量中,当我们需要添加新记录时,将为我们提供一个月和一年的值。
如果当前时间(用time()找到)大于$next_tuning变量-1个月,则返回任务是upcoming。如果在$next_tuning变量之后,则返回任务是late
我现在必须编写一个MySQL查询来列出即将返回或延迟返回的项。
我怎么用MySQL写这个?我对MySQL的功能不是很在行,如果有什么帮助我会非常感激的。
我的逻辑尝试是:
SELECT * FROM records
 // The next lines are to get the most recent month_last_tuned value and add the tuning_period variable
 WHERE
    NOW() > (SELECT tuning_date FROM tunings ORDER BY tuning_date ASC LIMIT 1)
       +
    (SELECT tuning_period FROM records WHERE records.id = INITIAL CUSTOMER ID)

我知道那是完全错误的。不过,逻辑差不多是这样的。
我的数据库架构如下:
php - 使用MySQL进行时间计算-LMLPHP
我希望从查询返回的行与上面PHP代码中的“late”或“coming”值相同。这意味着返回的行将在下一个优化日期(从上次优化加上优化周期计算)的1个月内。
谢谢!

最佳答案

您最好使用DateTime对象,而不是操作日期字符串。

$last_tuned = '2017-01-05';
$tuning_period = 3; // months

$dt_last_tuned = DateTimeImmutable::createFromFormat('Y-m-d',$last_tuned);
$dt_next_tuning = $dt_last_tuned->add(new DateInterval('P3M'));
$dt_now = new DateTimeImmutable();
$dt_tuning_upcoming = $dt_next_tuning->sub(new DateInterval('P1M'));

if( $dt_now > $dt_next_tuning) {
    return 'late';
}
if( $dt_now > $dt_tuning_upcoming) {
    return 'upcoming';
}

您还可以在MySQL查询中使用这些DateTime对象,方法是构建查询并根据需要传递类似于$dt_next_tuning->format('Y-m-d H:i:s');的内容。
但是,考虑到您的表结构,可能更容易获得所有相关记录并对其进行处理。很难确切地说明这些部分是如何组合在一起的,但一般来说,MySQL不应该用于“处理”内容。

关于php - 使用MySQL进行时间计算,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42613302/

10-11 12:46
查看更多