Desserializando datas JSON AJAX do lado do cliente
Pergunta
Dada a seguinte representação de data JSON:
"\/Date(1221644506800-0700)\/"
Como você desserializa isso em seu formato JavaScript do tipo data?
Tentei usar MS AJAX JavaScrioptSerializer conforme mostrado abaixo:
Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/")
No entanto, tudo que recebo é a data literal da string.
Solução
Desde que você sabe a corda é definitivamente uma data Eu prefiro fazer isso:
new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))
Outras dicas
Bertrand LeRoy, que trabalhou no ASP.NET Atlas / AJAX, descreveu o projeto da saída JavaScriptSerializer DateTime e revelou a origem das misteriosas esquerda e à direita barras. Ele fez esta recomendação:
executar uma pesquisa simples para "\ / Date ((\ d +)) \ /" e substituir por "new Date ($ 1)" antes do eval (Mas após a validação)
Eu implementei isso como:
var serializedDateTime = "\/Date(1271389496563)\/";
document.writeln("Serialized: " + serializedDateTime + "<br />");
var toDateRe = new RegExp("^/Date\\((\\d+)\\)/$");
function toDate(s) {
if (!s) {
return null;
}
var constructor = s.replace(toDateRe, "new Date($1)");
if (constructor == s) {
throw 'Invalid serialized DateTime value: "' + s + '"';
}
return eval(constructor);
}
document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");
Isto é muito perto de muitas das outras respostas:
- Use uma RegEx ancorada como Sjoerd Visscher se -. Não se esqueça do ^ e $
- Evite string.replace, eo 'g' ou 'i' opções em seu RegEx. "/ Date (1271389496563) // Data (1271389496563) /" não deve trabalho em tudo.
O valor de um JSON é uma string, número, objeto, array, verdadeiro, falso ou nulo. Portanto, esta é apenas uma string. Não há nenhuma maneira oficial para representar datas em JSON. Esta sintaxe é a partir da implementação asp.net ajax. Outros usam o formato ISO 8601.
Você pode analisá-lo como este:
var s = "\/Date(1221644506800-0700)\/";
var m = s.match(/^\/Date\((\d+)([-+]\d\d)(\d\d)\)\/$/);
var date = null;
if (m)
date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]);
A expressão regular usada nos olhares método deserialize ASP.net AJAX para uma string que se parece com "/ Date (1234) /" (A seqüência em si realmente precisa conter as aspas e barras). Para obter tal corda, você precisará escapar a citação e barra invertida caracteres, para que o código javascript para criar a aparência de corda como "\" \ / Date (1234) \ / \ "".
Este trabalho vontade.
Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800)\\/\"")
É meio estranho, mas eu descobri que eu tinha para serializar uma data, então serializar a string retornada de que, em seguida, desserializar no lado do cliente uma vez.
Algo como isso.
Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer();
string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now)));
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true);
Para aqueles que não querem usar o Microsoft Ajax, basta adicionar uma função de protótipo para a classe string.
por exemplo.
String.prototype.dateFromJSON = function () {
return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
};
Não quero usar eval? Tente algo simples como
var date = new Date(parseInt(jsonDate.substr(6)));
Como uma nota lateral, eu costumava pensar que a Microsoft estava enganosa usando este formato. No entanto, a especificação JSON não é muito clara quando se trata de definir uma maneira de descrever datas em JSON.
Na verdade, momentjs suporta este tipo de formato, você pode fazer algo como:
var momentValue = moment(value);
momentValue.toDate();
Isso retorna o valor em um formato de data javascript
O número é o tamanho do tempo padrão JS
new Date(1221644506800)
Wed 17 de setembro, 2008 19:41:46 GMT + 1000 (EST)