Como lidar
-
26-09-2019 - |
Pergunta
Eu acredito que estou perdendo algo óbvio aqui. Quando solicito uma resposta JSON de um serviço ODATA, recebo um resultado diferente para as propriedades do DateTime do que quando solicito XML. Vou usar o Feed Nerddinner Odata como exemplo.
JSON:
http://www.nerddinner.com/Services/OData.svc/Dinners(1)?$format=json
"EventDate": "\/Date(1235764800000)\/"
Xml:
http://www.nerddinner.com/Services/OData.svc/Dinners(1)
<d:EventDate m:type="Edm.DateTime">2009-02-27T20:00:00</d:EventDate>
Quando faço um alerta (nova data (1235764800000)) recebo este resultado:
Também recebo o resultado das 20h quando executo a mesma consulta com o Linqpad. Por que o fuso horário está incorreto no resultado do JSON? Parece assumir que a resposta está no GMT. Devo lidar com isso no cliente (via JavaScript) ou isso é algo que eu posso definir no servidor?
Estou usando o JQuery nos Serviços de Dados do Cliente e WCF (e Framework de entidade) no servidor.
Atualizar:
estou usando Datejs No lado do cliente, para lidar com a formatação do UTC DateTime. Estou me perguntando se essa é a maneira correta de realizar esse problema.
function getDateString(jsonDate) {
if (jsonDate == undefined) {
return "";
}
var utcTime = parseInt(jsonDate.substr(6));
var date = new Date(utcTime);
var minutesOffset = date.getTimezoneOffset();
return date.addMinutes(minutesOffset).toString("M/d/yyyy h:mm tt");
}
Solução
De acordo com Este link MSDN, DateTime
Objetos são ...
... representado no JSON como "/data (número de ticks)/". O número de carrapatos é um valor longo positivo ou negativo que indica o número de carrapatos (milissegundos) que se passaram desde a meia -noite de 01 de janeiro de 1970 UTC.
Então você está correto que .Net assume, mas é UTC em vez de GMT (embora eles são iguais). Há algum Boa respostas Aqui, para que forneça mais detalhes e também forneça métodos para analisar o JSON em uma data utilizável no cliente.
Quanto à conversão de datas de UTC para um fuso horário específico, no servidor, você pode usar o TimeZoneInfo
classe que tem um ConvertTimeFromUtc
método. Ou você pode escrever um conversor personalizado que herda do JavaScriptConverter
classe. Em JavaScript, existem o UTC
e getTimezoneOffset
métodos que podem ser usados.
Espero que isso ajude e boa sorte.
Outras dicas
Se isso pode ajudar, eu estava enfrentando o mesmo problema e acabei implementando algo assim, não tão elegante, mas funciona.
String.prototype.DateWCF = function(dateformat) {
return new Date(parseInt(this.match(/\/Date\(([0-9]+)(?:.*)\)\//)[1])).format(dateformat);
};
em seguida $.ajax
sucesso:
success: function(data) {
$.each(data, function() {
var hello = this.DateTimeProperty.DateWCF('dd-MM-yyyy'));
});
}
Espero que isso possa ser útil.
Isso deve funcionar bem:
var date = new Date(parseInt(jsonDate.substr(6)));
A função de substrato retira a parte "/date (", e a função Parseint recebe o número inteiro e ignora o ")/" no final.
Para as datas JSON formatadas ISO-8601, basta passar a string para o construtor de data:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Isso já estava consertado e discutiu que uma olhada nisso postagem anterior
Usando o script date.js abaixo
new Date(parseInt(yourDateValue)).toString("ddd, dd-MMM-yyyy, hh:mm:ss")
Se você estiver analisando as respostas do WCF JSON DATE em JavaScript, o Moment.js Date Framework remove grande parte da dor de cabeça: Moment.js - Parsing Asp.net JSON Datas. Ele também possui outros métodos úteis.
Nós produzimos data.js Como um cliente JavaScript para serviços ODATA. Se você estiver trabalhando em um cliente da Web, o uso desta biblioteca removerá essa dor de cabeça e também o impedirá de encontrar outras pessoas.
Data.js lida com todos os JSONP e outras preocupações em seu nome, facilitando e analisando os dados do JSON:
OData.read(
"http://services.odata.org/Northwind/Northwind.svc/Categories",
function (data) {
var html = "";
$.each(data.results, function(l) { html += "<div>" + l.CategoryName + "</div>"; });
$(html).appendTo($("#target-element-id"));
}
);
Experimente isso:
function getDate(datestr) {
return new Date(eval('new ' + datestr.replace(/\//g, '')));
}
Essa resposta pode ser votada (!!), mas uma solução alternativa é apenas alterar seu serviço WCF para retornar as datas de uma maneira mais amigável.
Aqui está uma amostra JSON do meu serviço WCF, mostrando um UpdateDateOriginal
Valor (usando a formatação padrão irritante que o WCF usou para o meu valor de tempo de dados) e um amigável UpdateDate
Versão do mesmo valor de tempo de dados.
Eu publiquei o código para fazer isso no seguinte artigo: