将实体复制到下周时安排更改会导致轮班

时间:2017-09-20 07:55:16

标签: php symfony doctrine-orm timezone timezone-offset

我的时区功能有一个错误,让我解释一下。 此功能的目标是将一周的用户事件复制到下周。

我有一个具有此属性的UserEvent模型

/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserEventRepository")
 */
class UserEvent
{
    /**
     * @ORM\Id()
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="datetime")
     */
    private $start;

    /**
     * @ORM\Column(type="datetime")
     */
    private $end;

    /**
     * @ORM\ManyToOne(targetEntity="UserEventType")
     * @ORM\JoinColumn(nullable=false)
     */
    private $type;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="userEvents")
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

    /* GETTERS AND SETTERS */
}

日期时间存储在UTC时区的日期库中,此时使用该应用程序的客户端位于Europe/Paris时区。

这是将事件复制到下周的逻辑

$newEvents = [];
foreach ($eventsToCopy as $event) {
    $newEvent = clone $event;
    $newEvent->getStart()->modify('+1 week');
    $newEvent->getEnd()->modify('+1 week');
    $newEvents[] = $newEvent;
}

这个周末是周末 问题出现在本周

周A :2017-10-23至2017-10-27

周B :2017-10-30至2017-11-03

第A周和第B周之间有一个时间更改时间表,因此第二周的计划时间会在小时前移动。

我无法对处理DateTime和时区进行高级更改,我只能修改此代码(遗留应用程序)

我对时区不太满意,也许我错过了一些明显的东西。

请给我你的神奇指导来解决这个问题! :)

1 个答案:

答案 0 :(得分:0)

我解决了我的问题:

  1. UTC从数据库转换为Europe/Paris
  2. 按照我想要的方式修改日期时间
  3. 然后我将我的欧洲/巴黎日期时间转换回UTC并将其保存在数据库中
  4. 代码示例

                $newEvent = new UserEvent();
                $newEvent->setUser($event->getUser());
                $newEvent->setType($event->getType());
    
                // Convert the datetimes of event to copy to Europe timezone
                // For my case I have only one timezone to handle at the moment, so it's always about Europe/Paris <=> UTC
                // In advanced use case you could convert the UTC datetime to the user's timezone
                list($start, $end) = $this->timezoneFormater->convertUTCDatetimeToEuropeDatetime([$event->getStart(), $event->getEnd()]);
    
                // Now set the date
                $start->modify('+1 week');
                $end->modify('+1 week');
    
                // Then convert back to UTC timezone
                list($start, $end) = $this->timezoneFormater->convertEuropeDatetimeToUTCDatetime([$start, $end]);
                $newEvent->setStart($start);
                $newEvent->setEnd($end);
    
                $newEvents[] = $newEvent;