在给定时间戳后查找给定时间的下一次出现
Find next occurance of a given time after given timestamp
给定任意时间戳(例如 2019-02-26 10:30:00
)我想找到下一次出现的任意时间。
例如,12:00:00
的下一次出现将是 2019-02-26 12:00:00
,而 09:00:00
的下一次出现将是第二天的 2019-02-27 09:00:00
。结果可能是 Carbon
或 Datetime
个对象。测试时间将只是一个字符串,如图所示。
有没有一种方法可以在原生 PHP 或 PHP Carbon 中进行计算,而无需在时间段内进行有条件的装箱。一个明显的方法是看被测试的时间是否超过today
的检查时间,如果是,则将结果作为检查时间加上24小时(第二天)。这对我来说就像是日期和时间的太多切碎和连接,所以有没有一种方法可以通过将时间视为一条简单的直线来计算它?
所有时间都将在一个时区内,使用夏令时。注意:任意日期时间和检查时间将不受 DST 转换影响,即 01:00
到 02:00
,因此希望它们不会成为需要考虑的问题。
PHP 的简短答案是否(部分答案,我不是 Carbon 的专家,但快速看一下它也是否,但您可以从以下代码创建一个宏)。
然而,在三元条件下,一行代码足够简单恕我直言(如果您想与当前日期和时间进行比较,请将第二个 DateTime($str)
替换为 DateTime()
,并更改 >=
by >
如果你希望第二天比较的时间完全相同):
$str = '2019-02-26 10:30:00';
$date1 = ( ($a = (new DateTime($str))->setTime(12,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
$date2 = ( ($a = (new DateTime($str))->setTime(9,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
echo $date1->format('Y-m-d H:i:s'); //2019-02-26 12:00:00
echo $date2->format('Y-m-d H:i:s'); //2019-02-27 09:00:00
快速说明:您给我们的不是时间戳,而是格式化日期。
这是我现在通过 Carbon
使用的内容,它似乎给了我正确的结果:
$dateTime = Carbon::parse('2019-03-30 17:34:50', 'Europe/London');
$testTime = '16:00:00';
list ($hour, $minute, $second) = explode(':', $testTime);
$nextTimeOccurrence = $dateTime
->copy() // Carbon 1 only
->hour($hour)->minute($minute)->second($second);
if ($dateTime->gt($nextTimeOccurrence)) {
$nextTimeOccurrence = $nextTimeOccurrence->addDay();
}
// $nextTimeOccurrence is the next occurrence of $testTime after $dateTime
时间的拆分看似笨拙,但也许是最好的方式?做法是:
- 创建一个时间戳,测试时间与我正在检查的时间戳在同一天。这将是我正在寻找的时间戳。
- 如果我正在检查的时间戳在上一步创建的时间戳之后,则添加一天。
我已经围绕 DST 测试了这个,很高兴 Carbon/Datetime 在 DST 期间添加一天时保持相同的时间,一天会有 25 小时或 23 小时,具体取决于它的方式去了。
我仍然认为有更多 "linear time" 的方法可以做到这一点,但这看起来简单而可靠。感谢办公室的@michael-stokoe 对我的领导。
给定任意时间戳(例如 2019-02-26 10:30:00
)我想找到下一次出现的任意时间。
例如,12:00:00
的下一次出现将是 2019-02-26 12:00:00
,而 09:00:00
的下一次出现将是第二天的 2019-02-27 09:00:00
。结果可能是 Carbon
或 Datetime
个对象。测试时间将只是一个字符串,如图所示。
有没有一种方法可以在原生 PHP 或 PHP Carbon 中进行计算,而无需在时间段内进行有条件的装箱。一个明显的方法是看被测试的时间是否超过today
的检查时间,如果是,则将结果作为检查时间加上24小时(第二天)。这对我来说就像是日期和时间的太多切碎和连接,所以有没有一种方法可以通过将时间视为一条简单的直线来计算它?
所有时间都将在一个时区内,使用夏令时。注意:任意日期时间和检查时间将不受 DST 转换影响,即 01:00
到 02:00
,因此希望它们不会成为需要考虑的问题。
PHP 的简短答案是否(部分答案,我不是 Carbon 的专家,但快速看一下它也是否,但您可以从以下代码创建一个宏)。
然而,在三元条件下,一行代码足够简单恕我直言(如果您想与当前日期和时间进行比较,请将第二个 DateTime($str)
替换为 DateTime()
,并更改 >=
by >
如果你希望第二天比较的时间完全相同):
$str = '2019-02-26 10:30:00';
$date1 = ( ($a = (new DateTime($str))->setTime(12,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
$date2 = ( ($a = (new DateTime($str))->setTime(9,00)) >= (new DateTime($str)) ) ? $a : $a->modify('+1 day');
echo $date1->format('Y-m-d H:i:s'); //2019-02-26 12:00:00
echo $date2->format('Y-m-d H:i:s'); //2019-02-27 09:00:00
快速说明:您给我们的不是时间戳,而是格式化日期。
这是我现在通过 Carbon
使用的内容,它似乎给了我正确的结果:
$dateTime = Carbon::parse('2019-03-30 17:34:50', 'Europe/London');
$testTime = '16:00:00';
list ($hour, $minute, $second) = explode(':', $testTime);
$nextTimeOccurrence = $dateTime
->copy() // Carbon 1 only
->hour($hour)->minute($minute)->second($second);
if ($dateTime->gt($nextTimeOccurrence)) {
$nextTimeOccurrence = $nextTimeOccurrence->addDay();
}
// $nextTimeOccurrence is the next occurrence of $testTime after $dateTime
时间的拆分看似笨拙,但也许是最好的方式?做法是:
- 创建一个时间戳,测试时间与我正在检查的时间戳在同一天。这将是我正在寻找的时间戳。
- 如果我正在检查的时间戳在上一步创建的时间戳之后,则添加一天。
我已经围绕 DST 测试了这个,很高兴 Carbon/Datetime 在 DST 期间添加一天时保持相同的时间,一天会有 25 小时或 23 小时,具体取决于它的方式去了。
我仍然认为有更多 "linear time" 的方法可以做到这一点,但这看起来简单而可靠。感谢办公室的@michael-stokoe 对我的领导。