使用 JMS 序列化程序的日期时间的反序列化和序列化之间的奇怪偏移

Strange Offset between De- and Serialization of Datetime with JMS Serializer

我正在开发一个日程安排应用程序,其前端通过基于 UNIX 时间戳的时间字段与后端通信。该应用程序已在生产环境中使用了将近一年,但突然之间,谢天谢地,只有在测试服务器上,每次保存和重新加载事件时,事件的时间戳都会增加 1 小时的偏移量。我无法在本地复制它。

这是我配置序列化程序的方式。

 /**
     * @ORM\Column(type="datetime")
     * @JMS\Type("DateTime<'U'>")
     */
    private $start;

错误示例:我在美国东部时间下午 4 点安排了一个活动。我的前端计算时间戳 1614870000,将其发送到服务器。当我重新加载时,我得到 1614873600 作为时间戳,当然,在我的前端显示为下午 5 点 MET。我可以重复这些步骤,保存并重新加载,我的活动将安排得越来越晚...

很明显,序列化和反序列化是不同步的。或者读取和写入数据库。但怎么可能呢?我已经尝试将 MySql 时区和 PHP 时区设置为荒谬的值(本地),但根本无法重现任何奇怪的行为。 (除此之外,我根本不知道系统是如何知道正确的时区的,因为显然它没有存储在数据库中,所以我认为事件至少应该在我切换时区时改变它们的开始时间,而它们不会' t.) 这是一个字段在数据库中的样子:

+---------------------+

| start               |

+---------------------+

| 2021-03-04 23:00:00 |

+---------------------+

这就是我从数据库中获取事件的方式:

$events = $repository->findAll();
        

        $serializer = $this->container->get('jms_serializer');
        $context = new SerializationContext();
        $context->setSerializeNull(true);
        $data = $serializer->serialize($events, 'json', $context);

这是saving/deserialization方面:

$event = $serializer->deserialize($request->getContent(), Event::class, 'json');
        $event->setLastEditUser($user);
        $event->setCreatedUser($user);
        $em = $this->getDoctrine()->getManager();
        $em->persist($event);
        $em->flush();

您对如何调试它有什么想法吗?或者为什么会发生这种情况?同样,此错误仅出现在测试服务器上,不幸的是,我无法直接访问该服务器,但请尝试与管理员联系。

好的,再研究一下,我想我明白了:

答案是 JMS 序列化程序和条令之间关于时区的不同缓存行为。服务器管理员以某种方式更改了时区。他说他将其更改为 Europe/Berlin(来自 UTC),我的调试输出显示相反的方式。反正。假设以下情况:

正在保存一个事件:

FE:“使用时间戳 1614956400 保存事件”

BE: "好的,JMS 序列化程序说我收到一个事件 $start = DateTime "2021/3/5 16:00:00 GMT+01:00" ( JMS 序列化程序默认时区似乎卡在缓存中。)

DB:“教义告诉我保存 2021/3/5 16:00:00”(<= 没有时区!)

...

正在加载该事件:

FE:“请再给我一次那个事件”

BE:“DB,你说什么?”

DB:“活动时间为 2021/3/5 16:00:00”

BE:“好的,学说,用它做一个 PHP DateTime...学说说它是 2021/3/5 16:00:00 UTC.JMS-Serializer,请告诉前端。好的,它的:1614960000"

Tadaaa。开始了。所以,我们有两个陷阱:

  1. Doctrines DateTime 不存储时区,在这种情况下会导致信息丢失,造成 space 误解。
  2. 默认时区的不同缓存导致不匹配...

所以,也许真正的问题是我选择了错误的学说数据类型?