yyyy - parse json date in jquery




Come si formatta una data Microsoft JSON? (20)

aggiornato

Abbiamo una libreria UI interna che deve far fronte sia al formato JSON di Microsoft ASP.NET, come /Date(msecs)/ , che è stato richiesto in origine, sia alla maggior parte del formato di data di JSON incluso JSON.NET, come 2014-06-22T00:00:00.0 . Inoltre, dobbiamo affrontare l'incapacità di oldie di far fronte a qualsiasi cosa tranne 3 posizioni decimali .

Prima rileviamo quale tipo di data stiamo consumando, lo analizziamo in un normale oggetto Date JavaScript, quindi lo formattiamo.

1) Rileva il formato della data di Microsoft

// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
    return /^\/Date\(/.test(s);
}

2) Rileva il formato della data ISO

var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;

function looksLikeIsoDate(s) {
    return isoDateRegex.test(s);
}

3) Formato della data MS Parse:

function parseMSDate(s) {
    // Jump forward past the /Date(, parseInt handles the rest
    return new Date(parseInt(s.substr(6)));
}

4) Formato della data ISO Parse.

Almeno abbiamo un modo per essere sicuri che abbiamo a che fare con date ISO standard o date ISO modificate per avere sempre tre millisecondi ( vedi sopra ), quindi il codice è diverso a seconda dell'ambiente.

4a) Formato standard per la data ISO standard, per far fronte ai problemi di oldie:

function parseIsoDate(s) {
    var m = isoDateRegex.exec(s);

    // Is this UTC, offset, or undefined? Treat undefined as UTC.
    if (m.length == 7 ||                // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
        (m.length > 7 && (
            !m[7] ||                    // Array came back length 9 with undefined for 7 and 8
            m[7].charAt(0) != '.' ||    // ms portion, no tz offset, or no ms portion, Z
            !m[8] ||                    // ms portion, no tz offset
            m[8] == 'Z'))) {            // ms portion and Z
        // JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
        var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
    } else {
        // local
        var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
    }

    return d;
}

4b) Formato Parse ISO con cifre decimali fisse di tre millisecondi: molto più semplice:

function parseIsoDate(s) {
    return new Date(s);
}

5) Formattalo:

function hasTime(d) {
    return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}

function zeroFill(n) {
    if ((n + '').length == 1)
        return '0' + n;

    return n;
}

function formatDate(d) {
    if (hasTime(d)) {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
        s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
    } else {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
    }

    return s;
}

6) Lega tutto insieme:

function parseDate(s) {
    var d;
    if (looksLikeMSDate(s))
        d = parseMSDate(s);
    else if (looksLikeIsoDate(s))
        d = parseIsoDate(s);
    else
        return null;

    return formatDate(d);
}

La precedente risposta è utile per legare questa formattazione della data al parsing JSON di jQuery in modo da ottenere oggetti Date invece di stringhe o se in qualche modo sei ancora bloccato in jQuery <1.5.

Vecchia risposta

Se stai utilizzando la funzione Ajax di jQuery 1.4 con ASP.NET MVC, puoi trasformare tutte le proprietà DateTime in oggetti Date con:

// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};

$.ajax({
    ...
    dataFilter: function(d) {
        return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
    },
    ...
});

In jQuery 1.5 è possibile evitare di parseJSON l'override del metodo parseJSON livello globale utilizzando l'opzione convertitori nella chiamata Ajax.

http://api.jquery.com/jQuery.ajax/

Sfortunatamente devi passare alla vecchia eval route per far sì che le date vengano analizzate globalmente sul posto, altrimenti è necessario convertirle in base al caso dopo l'analisi caso per caso.

Sto prendendo il mio primo crack Ajax con jQuery. Inserisco i miei dati nella mia pagina, ma sto riscontrando dei problemi con i dati JSON restituiti per i tipi di dati Date. Fondamentalmente, sto ottenendo una stringa che assomiglia a questo:

/Date(1224043200000)/

Da qualcuno totalmente nuovo a JSON - Come faccio a formattarlo in un formato a data breve? Questo dovrebbe essere gestito da qualche parte nel codice jQuery? Ho provato il plugin jQuery.UI.datepicker usando $.datepicker.formatDate() senza alcun successo.

A proposito: ecco la soluzione che ho trovato usando una combinazione delle risposte qui:

function getMismatch(id) {
  $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
      $("#AuthMerchId").text(result.AuthorizationMerchantId);
      $("#SttlMerchId").text(result.SettlementMerchantId);
      $("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
      $("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
      $("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
      $("#LastUpdatedBy").text(result.LastUpdateNt);
      $("#ProcessIn").text(result.ProcessIn);
    }
  );

  return false;
}

function formatJSONDate(jsonDate) {
  var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
  return newDate;
}

Questa soluzione ha ottenuto il mio oggetto dal metodo di callback e ha mostrato correttamente le date sulla pagina utilizzando la libreria del formato della data.


Non ripeterti: automatizza la conversione della data utilizzando $.parseJSON()

Le risposte al tuo post forniscono la conversione manuale della data in date JavaScript. Ho esteso un po ' $.parseJSON() jQuery, quindi è in grado di analizzare automaticamente le date quando lo istruisci. Elabora le date in formato ASP.NET ( /Date(12348721342)/ ) così come le date formattate ISO ( 2010-01-01T12.34.56.789Z ) supportate dalle funzioni JSON native nei browser (e librerie come json2.js).

Comunque. Se non desideri ripetere più volte il codice di conversione della data, ti suggerisco di leggere questo post sul blog e ottenere il codice che ti semplificherà la vita.


È anche possibile utilizzare la libreria JavaScript http://momentjs.com/ , che risulta utile quando si pianifica di trattare formati diversi localizzati ed eseguire altre operazioni con valori di date:

function getMismatch(id) {
    $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
        $("#AuthMerchId").text(result.AuthorizationMerchantId);
        $("#SttlMerchId").text(result.SettlementMerchantId);
        $("#CreateDate").text(moment(result.AppendDts).format("L"));
        $("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
        $("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
        $("#LastUpdatedBy").text(result.LastUpdateNt);
        $("#ProcessIn").text(result.ProcessIn);
    }
    );
    return false;
}

Configurare la localizzazione è facile come aggiungere i file di configurazione (li trovi su momentjs.com) al tuo progetto e configurare la lingua:

moment.lang('de');

Aggiungi il plug-in dell'interfaccia utente jQuery nella tua pagina:

function DateFormate(dateConvert) {
    return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};

Di seguito è una soluzione piuttosto semplice per l'analisi delle date JSON. Usa le seguenti funzioni secondo i tuoi requisiti. Devi solo passare il formato JSON Data recuperata come parametro per le funzioni seguenti:

function JSONDate(dateStr) {
    var m, day;
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    return (m + '/' + day + '/' + d.getFullYear())
}

function JSONDateWithTime(dateStr) {
    jsonDate = dateStr;
    var d = new Date(parseInt(jsonDate.substr(6)));
    var m, day;
    m = d.getMonth() + 1;
    if (m < 10)
        m = '0' + m
    if (d.getDate() < 10)
        day = '0' + d.getDate()
    else
        day = d.getDate();
    var formattedDate = m + "/" + day + "/" + d.getFullYear();
    var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
    var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
    var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
    formattedDate = formattedDate + " " + formattedTime;
    return formattedDate;
}

Eval non è necessario. Questo funzionerà bene:

var date = new Date(parseInt(jsonDate.substr(6)));

La funzione substr prende la parte "/ Date (", e la funzione parseInt ottiene il numero intero e ignora ") /" alla fine. Il numero risultante viene passato al costruttore Date.

EDIT: ho intenzionalmente omesso la radice (il secondo argomento di parseInt); vedi il mio commento qui sotto . Inoltre, sono completamente d'accordo con il commento di Rory : le date ISO-8601 sono preferite rispetto a questo vecchio formato - quindi questo formato generalmente non dovrebbe essere usato per nuovi sviluppi. Scopri l'eccellente libreria Json.NET per un'ottima alternativa che serializza le date utilizzando il formato ISO-8601.

Per le date JSON formattate ISO-8601, basta passare la stringa nel costruttore Date:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support

Ho anche dovuto cercare una soluzione a questo problema e alla fine mi sono imbattuto in moment.js che è una bella libreria in grado di analizzare questo formato data e molti altri.

var d = moment(yourdatestring)

Mi ha salvato un po 'di mal di testa quindi ho pensato di condividerlo con te. :)
Puoi trovare qualche informazione in più qui: http://momentjs.com/


Ho finito per aggiungere i "caratteri nell'espressione regolare di Panos per sbarazzarsi di quelli generati dal serializzatore Microsoft per quando si scrivono oggetti in uno script inline:

Quindi se hai una proprietà nel tuo code-behind C # code-behind è qualcosa di simile

protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}

E nel tuo aspx hai

<script type="text/javascript">
    var myObject = '<%= JsonObject %>';
</script>

Otterresti qualcosa di simile

var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';

Notare le doppie virgolette.

Per ottenere questo in una forma che la valutazione ha correttamente deserializzato, ho usato:

myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');

Io uso Prototype e per usarlo ho aggiunto

String.prototype.evalJSONWithDates = function() {
    var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
    return jsonWithDates.evalJSON(true);
}

In jQuery 1.5, finché hai json2.js per coprire i browser più vecchi, puoi deserializzare tutte le date che arrivano da Ajax come segue:

(function () {
    var DATE_START = "/Date(";
    var DATE_START_LENGTH = DATE_START.length;

    function isDateString(x) {
        return typeof x === "string" && x.startsWith(DATE_START);
    }

    function deserializeDateString(dateString) {
        var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
        var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
        return utcDate;
    }

    function convertJSONDates(key, value) {
      if (isDateString(value)) {
        return deserializeDateString(value);
      }
      return value;
    }

    window.jQuery.ajaxSetup({
      converters: {
        "text json": function(data) {
          return window.JSON.parse(data, convertJSONDates);
        }
      }
    });
}());

Ho incluso la logica che presuppone che tu invii tutte le date dal server come UTC (che dovresti); il consumatore ottiene quindi un oggetto Date JavaScript con il valore di zecche appropriato per riflettere questo. Cioè, chiamare getUTCHours() , ecc. getUTCHours() data restituirà lo stesso valore che ha sul server, e chiamando getHours() restituirà il valore nel fuso orario locale dell'utente come determinato dal loro browser.

Questo non tiene conto del formato WCF con offset del fuso orario, anche se sarebbe relativamente facile aggiungerlo.


L'esempio originale:

/Date(1224043200000)/  

non riflette la formattazione utilizzata da WCF quando si inviano le date tramite WCF REST utilizzando la serializzazione JSON incorporata. (almeno su .NET 3.5, SP1)

Ho trovato la risposta utile, ma è necessaria una leggera modifica alla regex, poiché sembra che l'offset GMT del fuso orario sia stato aggiunto al numero restituito (dal 1970) in WCF JSON.

In un servizio WCF ho:

[OperationContract]
[WebInvoke(
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.WrappedRequest
    )]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );

ApptVisitLinkInfo è definito semplicemente:

public class ApptVisitLinkInfo {
    string Field1 { get; set; }
    DateTime Field2 { get; set; }
    ...
}

Quando "Field2" viene restituito come Json dal servizio, il valore è:

/Date(1224043200000-0600)/

Si noti l'offset del fuso orario incluso come parte del valore.

La regex modificata:

/\/Date\((.*?)\)\//gi

È leggermente più impaziente e afferra tutto tra i paren, non solo il primo numero. Il tempo risultante 1970, oltre allo sfasamento del fuso orario, possono essere tutti inseriti nell'eval per ottenere un oggetto data.

La riga risultante di JavaScript per la sostituzione è:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");

Non esiste un tipo di data incorporato in JSON . Sembra il numero di secondi / millisecondi di qualche epoca. Se conosci l'epoca, puoi creare la data aggiungendo la giusta quantità di tempo.


Non pensarci troppo. Come abbiamo fatto per decenni, passare un offset numerico dall'epoca standard di fatto del 1 gennaio 1970 a mezzanotte GMT / UTC / & c in numero di secondi (o millisecondi) da questa epoca. A JavaScript piace, piace a Java, piace a C e piace a Internet.


Per coloro che utilizzano Newtonsoft Json.NET , leggi come farlo tramite Native JSON in IE8, Firefox 3.5 e Json.NET .

È utile anche la documentazione sulla modifica del formato delle date scritte da Json.NET: Serializzare le date con Json.NET

Per quelli che sono troppo pigri, ecco i passi veloci. Poiché JSON ha un'implementazione DateTime libera, è necessario utilizzare IsoDateTimeConverter() . Si noti che dal momento che Json.NET 4.5 il formato data predefinito è ISO, quindi il codice sottostante non è necessario.

string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());

Il JSON passerà come

"fieldName": "2009-04-12T20:44:55"

Infine, alcuni JavaScript per convertire la data ISO in una data JavaScript:

function isoDateReviver(value) {
  if (typeof value === 'string') {
    var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
      if (a) {
        var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
        return new Date(utcMilliseconds);
      }
  }
  return value;
}

L'ho usato così

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);

Pubblicare nel thread fantastico:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));

Questo è frustrante. La mia soluzione era di analizzare "/ e /" dal valore generato dal JavaScriptSerializer di ASP.NET in modo che, anche se JSON potrebbe non avere un valore letterale di data, viene comunque interpretato dal browser come una data, il che è tutto ciò che veramente voglio: {"myDate":Date(123456789)}

JavaScriptConverter personalizzato per DateTime?

Devo sottolineare l'accuratezza del commento di Roy Tinker. Questo non è legale JSON. È un trucco sporco e sporco sul server per rimuovere il problema prima che diventi un problema per JavaScript. Soffocherà un parser JSON. L'ho usato per scendere da terra, ma non lo uso più. Tuttavia, ritengo ancora che la risposta migliore risieda nel cambiare il modo in cui il server formatta la data, ad esempio ISO come accennato altrove.


Se dici in JavaScript,

var thedate = new Date(1224043200000);
alert(thedate);

vedrai che è la data corretta e puoi utilizzarla ovunque nel codice JavaScript con qualsiasi framework.


Un post in ritardo, ma per coloro che hanno cercato questo post.

Immagina questo:

    [Authorize(Roles = "Administrator")]
    [Authorize(Roles = "Director")]
    [Authorize(Roles = "Human Resources")]
    [HttpGet]
    public ActionResult GetUserData(string UserIdGuidKey)
    {
        if (UserIdGuidKey!= null)
        {
            var guidUserId = new Guid(UserIdGuidKey);
            var memuser = Membership.GetUser(guidUserId);
            var profileuser = Profile.GetUserProfile(memuser.UserName);
            var list = new {
                              UserName = memuser.UserName,
                              Email = memuser.Email ,
                              IsApproved = memuser.IsApproved.ToString() ,
                              IsLockedOut = memuser.IsLockedOut.ToString() ,
                              LastLockoutDate = memuser.LastLockoutDate.ToString() ,
                              CreationDate = memuser.CreationDate.ToString() ,
                              LastLoginDate = memuser.LastLoginDate.ToString() ,
                              LastActivityDate = memuser.LastActivityDate.ToString() ,
                              LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
                              IsOnline = memuser.IsOnline.ToString() ,
                              FirstName = profileuser.FirstName ,
                              LastName = profileuser.LastName ,
                              NickName = profileuser.NickName ,
                              BirthDate = profileuser.BirthDate.ToString() ,
            };
            return Json(list, JsonRequestBehavior.AllowGet);
        }
        return Redirect("Index");
    }

Come puoi vedere, sto utilizzando la funzione di C # 3.0 per la creazione di Generics "Auto". È un po 'pigro, ma mi piace e funziona. Solo una nota: Profile è una classe personalizzata che ho creato per il mio progetto di applicazione web.


Questo può anche aiutarti.

 function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
        var pattern = /Date\(([^)]+)\)/;
        var results = pattern.exec(value);
        var dt = new Date(parseFloat(results[1]));
        return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
    }

Cosa succede se .NET restituisce ...

return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"

E poi in JavaScript ...

var x = new Date("2013-09-17 15:18:53Z");

var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

C'è un'altra opzione senza usare la libreria jQuery?





json