Domanda

La mia stringa JSON contiene un campo data che restituisce tale valore:

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

Sono particolarmente interessato a parsing solo la non vano data l'ora. Ho provato ad utilizzare una funzione reviver, ma è interessante notare la funzione reviver non viene richiamato! (Provato su Firefox)

Ecco il mio codice per realizzare questo:

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 non chiama mai dateReviver.

Ho investito un giorno intero ma senza fortuna! Qualcuno può aiutarmi?

È stato utile?

Soluzione

  1. L'espressione regolare si aspetta un fuso orario "Zulu" (Un carattere 'Z' alla fine), mentre la stringa di esempio data-ora mostra un fuso orario numerica ( '-04: 00'). La seguente espressione regolare accetterà sia:

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

    Se le cifre di fuso orario non sono pari a zero, si potrebbe desiderare di modificare realmente la data dopo l'analisi e / o la conversione in UTC, a rispettare il fuso orario.

  2. Posso vedere dateReviver () essere colpito. Provare quanto segue in un browser:

    <!-- 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>
    

    Sto ottenendo il seguente nel browser, che indica l'analisi di successo:

    Sat Apr 4 15:55:16 PDT 2009
    

Altri suggerimenti

Utilizzando TypeSript, la mia soluzione è la seguente:

    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;
}

Il meglio di tutti i mondi ;-) Si avvale di un datereviver anonime, che viene chiamato da JSON.parse su ogni proprietà. La logica reviver è quello di verificare se la proprietà è di tipo stringa e in caso affermativo, se sembra che l'inizio di una data ... Se si tratta di una data, poi lasciare new Date (valore) fare il parsing reale ... tutte le variazioni di fuso orario sono supportati in questo modo.

Speranza che aiuta!

L'estensione della regolazione convertitori jQuery.ajax funzionato bene per me dalla sua di default:

"text json": jQuery.parseJSON

a

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

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

non regolare la data per le informazioni fuso orario, il -4:00 nell'esempio.

Un'alternativa è quella di lasciare Date () fare il parsing per voi:

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

Se il JSON era stato formattato con JSON.stringify () sarebbe stato in 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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top