Pergunta

Minha string json contém um campo de data que retorna esse valor:

"2009-04-04T22:55:16.0000000-04:00"

Estou particularmente interessado em analisar apenas o compartimento da data e não a hora. Tentei usar uma função Reviver, mas, curiosamente, a função Reviver nunca foi invocada! (Tentado no Firefox)

Aqui está o meu código para realizar isso:

var Site = {
.....
dateReviver: function(key, value) {
    var a;
    if (typeof value === 'string') {
        a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
        if (a) {
            return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                            +a[5], +a[6]));
        }
    }
    return value;
},
loadArticle: function(id) {
....
    proxy.getArticle(id, function(response) {
        var data = JSON.parse(response.result, Site.dateReviver);
        ....
    });
}
};

Json.parse in loadArticle nunca liga dateReviver.

Eu investi um dia inteiro, mas sem sorte! Alguém poderia me ajudar, por favor?

Foi útil?

Solução

  1. A expressão regular espera um fuso horário "Zulu" (um caractere 'Z' no final), enquanto a sequência de data de data da amostra mostra um fuso horário numérico ('-04: 00'). O seguinte Regex aceitará os dois:

    /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(Z|([+\-])(\d{2}):(\d{2}))$/
    

    Se os dígitos do fuso horário não forem zero, convém modificar a data após a análise e/ou converter para o UTC, para respeitar o fuso horário.

  2. Eu posso ver DateReviver () sendo atingido. Experimente o seguinte em um navegador:

    <!-- saved from url=(0014)about:internet -->
    <html>
        <head>
            <script src="http://www.json.org/json2.js"></script>
            <script type="text/javascript" src="http://ajax.Microsoft.com/ajax/jQuery/jquery-1.3.2.js"></script>
            <script>
                $(function () {
                    // a mock proxy to return some json to play with
                    var proxy = {
                        getArticle: function(id, foo) { foo({
                            result: '["2009-04-04T22:55:16.0000000-04:00"]'
                        }); }
                    };
                    // the origial Site object, with the fixed regex
                    var Site = {
                        dateReviver: function(key, value) {
                            var a;
                            if (typeof value === 'string') {
                                a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(Z|([+\-])(\d{2}):(\d{2}))$/.exec(value);
                                if (a) {
                                    return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
                                                    +a[5], +a[6]));
                                }
                            }
                            return value;
                        },
                        loadArticle: function(id) {
                            proxy.getArticle(id, function(response) {
                                var data = JSON.parse(response.result, Site.dateReviver);
                                // put the parsed JSON date on the page
                                $("#output").html(data[0].toString());
                            });
                        }
                    };
                    // try out our Site object
                    Site.loadArticle();
                });
            </script>
        </head>
        <body>
            <div id="output"></div>
        </body>
    </html>
    

    Estou recebendo o seguinte no navegador, indicando análise bem -sucedida:

    Sat Apr 4 15:55:16 PDT 2009
    

Outras dicas

Usando o TypeRipt, minha solução é a seguinte:

    export function parseWithDate(jsonString: string): any {
    var reDateDetect = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/;  // startswith: 2015-04-29T22:06:55
    var resultObject = JSON.parse(jsonString,(key: any, value: any) => {
        if (typeof value == 'string' && (reDateDetect.exec(value))) {
            return new Date(value);
        }
        return value;
    });
    return resultObject;
}

O melhor de todos os mundos ;-) Ele usa um datereviver anônimo, que é chamado pelo JSON.Parse em cada propriedade. A lógica do Reviver é verificar se a propriedade é da string do tipo e, em caso afirmativo, se parece com o início de uma data ... se for uma data, deixe uma nova data (valor) fazer a análise real ... todos As variações do fuso horário são suportadas dessa maneira.

Espero que ajude!

Estendendo a configuração do JQuery.AJAX Converters funcionou bem para mim do seu padrão:

"text json": jQuery.parseJSON

para

"text json": function (xmlValue) {
            var value = JSON.parse(xmlValue, Site.dateReviver);
      return value;
      } 

O uso de return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]));

não ajusta a data para as informações do fuso horário, o -4:00 no exemplo.

Uma alternativa é deixar Date () fazer a análise para você:

var dateReviver = function (key, value) {
    var a;
    if (typeof value === 'string') {
        a = Date.parse(value);
        if (a) {
            return new Date(a);
        }    
    }
    return value;
}

Se o JSON tivesse sido formatado com JSON.Stringify (), estaria no UTC (Z).

function dateReviver (k,v) {

    var isnum = /^\d+$/.test(v);

    // Check if number since Date.parse(number) returns valid date
    if (isnum) {
        return v;
    }

    if (Date.parse(v)) {
        return new Date(Date.parse(v));
    }
    return v;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top