日期减去 10 分钟在 symfony 中循环



我有一个循环,从今天开始到旧日期,将日期递减为每个循环 10 分钟

代码仅在我的 Symfony 2.8 中出现问题... 我在没有 Symfony 的情况下重写代码进行测试,它可以工作......


<?php
$start = new DateTime('2017-01-21T02:20:00+01:00');
$current = new DateTime('2019-01-01T02:20:00+01:00');
function dateIntervalToSeconds(DateInterval $dateInterval)
{
$reference = new DateTimeImmutable;
$endTime = $reference->add($dateInterval);
return $endTime->getTimestamp() - $reference->getTimestamp();
}
function subDateIntervalToDatetime(DateTime $dateTime, DateInterval $dateInterval)
{
$newTimestamp = $dateTime->getTimestamp() - dateIntervalToSeconds($dateInterval);
// return new DateTime("@$newTimestamp", $dateTime->getTimezone()); <= timezone isn't set properly ...
$newDate = new DateTime("@$newTimestamp");
$newDate->setTimezone($dateTime->getTimezone());
return $newDate;
}
$i = 0;
while($current->getTimestamp() > $start->getTimestamp()) {
echo $i . ' '. $current->format('Y-m-d H:i:s') . ' -> ' . $start->format('Y-m-d H:i:s') . "rn";
$current = subDateIntervalToDatetime($current, new DateInterval('PT10M'));
$i++;
}

但是在我的symfony上下文中,subDateIntervalToDatetime函数说:2018-10-28 02:00:00减去10分钟是2018-10-28 02:50:00

脚本仅在此日期出现此错误...

我在函数中添加此代码:

echo $dateTime->format('Y-m-d H:i:s') . ' -> ' . $newDate->format('Y-m-d H:i:s') . "rn";
if ($dateTime  < $newDate) {
die;
}

但永远不要输入如果...

我只是用这个回声代替回声

echo $dateTime->format('Y-m-d H:i:s') . ' ' . $dateTime->getTimestamp() .' -> ' . $newDate->format('Y-m-d H:i:s') . ' ' . $newDate->getTimestamp() . "rn";

现在我经历了如果...但我总是有主要问题...

你能解释为什么吗?以及如何解决它? (为什么这个日期特别?

PS:在视频 https://streamable.com/3vkxn 中寻找乐趣

编辑,我的symfony项目中的函数:

protected function findMissingIntervals(ProbeData $probeData, $nbMissingValue, DateTime $dateStart, DateTime $dateEnd)
{
/** @var ProbeDataValueRepository $probeDataValueRepository */
$probeDataValueRepository = $this->em->getRepository(ProbeDataValue::class);
/** @var ProbeDataValue[} $data */
$data = $probeDataValueRepository->findDataByProbeDataIndexedByDate($probeData, 'DESC');
$currentDate = clone($dateEnd);
$currentError = 0;
$globalError = [];
$tempErrorRange = null;
while ($currentDate->getTimestamp() > $dateStart->getTimestamp() || $currentError < $nbMissingValue) {
$exist = array_key_exists($currentDate->format('Y-m-d H:i:s'), $data);
// inc count current Error
if (!$exist) {
$currentError++;
if ($tempErrorRange === null) {
$tempErrorRange = [
'end' => clone($currentDate),
];
}
} else {
if ($tempErrorRange !== null) {
$tmpDate = clone($currentDate);
$tempErrorRange['start'] = $tmpDate->add(new DateInterval('PT10M'));
$globalError[] = $tempErrorRange;
$tempErrorRange = null;
}
}
// $currentDate = StaticHelper::subDateIntervalToDatetime($currentDate, new DateInterval('PT10M'));
$currentDate = $currentDate->sub(new DateInterval('PT10M'));
dump($currentDate->format("Y-m-d H:i:s"));
}
$this->displayErrorIntervals($globalError);
return $globalError;
}

我认为你做了太多不必要的逻辑。对我来说,这只是通过减去间隔来正确使用日期时间

<?php
$start = new DateTime('2017-01-21T02:20:00+01:00');
$current = new DateTime('2019-01-01T02:20:00+01:00');
$tenMinInterval = new DateInterval('PT10M');

for($i = 0; $current > $start; ++$i) {
echo $i . ' '. $current->format('Y-m-d H:i:s') . ' -> ' . $start->format('Y-m-d H:i:s') . "rn";  
$current->sub($tenMinInterval);
}

输出:

0 2019-01-01 02:20:00 -> 2017-01-21 02:20:00
1 2019-01-01 02:10:00 -> 2017-01-21 02:20:00
2 2019-01-01 02:00:00 -> 2017-01-21 02:20:00
3 2019-01-01 01:50:00 -> 2017-01-21 02:20:00
4 2019-01-01 01:40:00 -> 2017-01-21 02:20:00
5 2019-01-01 01:30:00 -> 2017-01-21 02:20:00
6 2019-01-01 01:20:00 -> 2017-01-21 02:20:00
7 2019-01-01 01:10:00 -> 2017-01-21 02:20:00
8 2019-01-01 01:00:00 -> 2017-01-21 02:20:00
9 2019-01-01 00:50:00 -> 2017-01-21 02:20:00
10 2019-01-01 00:40:00 -> 2017-01-21 02:20:00
11 2019-01-01 00:30:00 -> 2017-01-21 02:20:00
12 2019-01-01 00:20:00 -> 2017-01-21 02:20:00
13 2019-01-01 00:10:00 -> 2017-01-21 02:20:00
14 2019-01-01 00:00:00 -> 2017-01-21 02:20:00
15 2018-12-31 23:50:00 -> 2017-01-21 02:20:00
16 2018-12-31 23:40:00 -> 2017-01-21 02:20:00

关于您的案例,您正在使用时区和时间戳,当您将日期时间转换为时间戳时,您会丢失有关时区的信息。如果要包含时区,请在$start中设置它们,$current DateTime 构造函数,如果要将其转换为其他构造函数,请在 DateTime 上使用 setTimezone((。

最新更新