DateTime响应字符串的Symfony序列化程序

时间:2018-04-08 12:20:42

标签: symfony serialization

当尝试执行一个doctrine查询并将其序列化为json(不使用JSM,使用symfony序列化程序)时,我在json中得到以下内容:

""由于" {"时区" {"名称":"欧/柏林"&#34 ;过渡":[{" TS": - 2147483648"时间":" 1901-12-13T20:45:52 + 0000"&# 34;偏移":3208," isdst":假,"缩写":" LMT"},{" TS": - 2147483648"时间":" 1901-12-13T20:45:52 + 0000""偏移":3600," isdst&#34 ;:假,"缩写":" CET"},{" TS": - 1693706400"时间":" 1916至1904年-30T22:00:00 + 0000""偏移":7200," isdst":真,"缩写":" CEST&#34 ;},{" TS": - 1680483600"时间":" 1916-09-30T23:00:00 + 0000""偏移&# 34;:3600," isdst":假,"缩写":" CET"},{" TS": - 1663455600&# 34;时间":" 1917-04-16T01:00:00 + 0000""偏移":7200," isdst":真,&# 34;缩写":" CEST"},{" TS": - 1650150000"时间":" 1917-09-17T01:00 :00 + 0000""偏移":3600," isdst":假,"缩写":" CET&# 34;},{" TS": - 1632006000"时间":" 1918-04-15T01:00:00 + 0000""偏移& #34;:7200," isdst":真,"缩写":" CEST"},{" TS": - 1618700400,& #34;时间":" 1918-09-16T01:00:00 + 0000""偏移":3600," isdst":假,& #34;缩写":" CET"},{" TS": - 938905200"时间":" 1940-04-01T01: 00:00 + 0000""偏移":7200," isdst":真,"缩写":" CEST"}, {" TS": - 857257200"时间":" 1942-11-02T01:00:00 + 0000""偏移&#34 ;: 3600" isdst":假,"缩写":" CET"},{" TS": - 844556400"时间& #34;:" 1943-03-29T01:00:00 + 0000""偏移":7200," isdst":真,"缩写& #34;:" CEST"},{" TS": - 828226800"时间":" 1943-10-04T01:00:00+ 0000""偏移":3600," isdst":假,"缩写":" CET"},{&#34 ; TS": - 812502000"时间":" 1944-04-03T01:00:00 + 0000""偏移":7200,&# 34; isdst":真,"缩写":" CEST"},{" TS": - 796777200"时间&#34 ;: " 1944-10-02T01:00:00 + 0000""偏移":3600,"

存储截止日期时,会保存时区并存储其他时区字段。有没有办法以特定格式提取日期或指定检索时使用的时区?

 public function blahAction(Request $request)
{
    $currentUser = $this->getUser();
    $em = $this->getDoctrine()->getManager();
    $blahs = $em->getRepository('AppBundle:blah')->findAllByStatus($currentUser,'TODO');
    $encoders = array(new XmlEncoder(), new JsonEncoder());
    $normalizer = array(new ObjectNormalizer());
    $serializer = new Serializer($normalizer, $encoders);
    $response = new Response($serializer->serialize($blahs, 'json'));
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

3 个答案:

答案 0 :(得分:5)

您有2种方法可以获得RFC3339日期时间格式...

选项1:

将DateTimeNormalizer添加为规范化程序。一个例子是https://symfony.com/doc/current/components/serializer.html#recursive-denormalization-and-type-safety

更改

$normalizer = array(new ObjectNormalizer());

通过

$normalizer = array(new DateTimeNormalizer(), new ObjectNormalizer());

选项2

更简单的是使用“序列化程序”容器服务......您的代码看起来像......

public function blahAction(Request $request)
{
    $currentUser = $this->getUser();
    $em = $this->getDoctrine()->getManager();
    $blahs = $em->getRepository('AppBundle:blah')->findAllByStatus($currentUser,'TODO');
    $response = new Response($this->get('serializer')->serialize($blahs, 'json'));
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

..或者,如果您更喜欢自动装配方式(此代码未选中)

public function blahAction(Request $request, \Symfony\Component\Serializer\SerializerInterface $serializer)
{
    $currentUser = $this->getUser();
    $em = $this->getDoctrine()->getManager();
    $blahs = $em->getRepository('AppBundle:blah')->findAllByStatus($currentUser,'TODO');
    $response = new Response($serializer->serialize($blahs, 'json'));
    $response->headers->set('Content-Type', 'application/json');
    return $response;
}

答案 1 :(得分:1)

在Symfony 5.1中,建议添加一个回调函数以指定日期时间字段格式。例如:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;


$dateCallback = function ($innerObject, $outerObject, string $attributeName, string $format = null, array $context = []) {
        return $innerObject instanceof \DateTime ? $innerObject->format(\DateTime::ISO8601) : '';
    };

    $defaultContext = [
        AbstractNormalizer::CALLBACKS => [
            'created_at' => $dateCallback,
            'updated_at' => $dateCallback
        ],
        AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER =>
            function ($articles, $format, $context)  {
                return $articles->getId();
            }
    ];

    $encoders = [new JsonEncoder()];
    $normalizers = [
        new ObjectNormalizer(null, null, null,
            null, null, null,
            $defaultContext)
    ];

    $serializer = new Serializer(
        $normalizers, $encoders
    );

    $articles = $serializer->serialize($articles, 'json');

其中 $ articles = App \ Entity \ Article 对象的数组

您可以在回调函数中指定所需的日期时间格式。

答案 2 :(得分:0)

另一种选择是将参数传递到unique:users,email|unique:clients,email中的默认(!password.equals(PASSWORD) && !username.equals(USERNAME)) != (!password.equals(PASSWORD) || !username.equals(USERNAME) )

DateTimeNormalizer