Como formatar uma data JSON da Microsoft?

2000

Estou dando meu primeiro acesso ao Ajax com jQuery. Estou colocando meus dados em minha página, mas estou tendo problemas com os dados JSON retornados para os tipos de dados Date. Basicamente, estou recebendo uma string de volta que fica assim:

/Date(1224043200000)/

De alguém totalmente novo para o JSON - Como formatar isso para um formato de data curto? Isso deve ser tratado em algum lugar do código jQuery? Eu tentei ojQuery.UI.datepicker plugin usando $.datepicker.formatDate()sem sucesso.

FYI: Aqui está a solução que eu encontrei usando uma combinação das respostas aqui:

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

Essa solução pegou meu objeto no método de retorno de chamada e exibiu as datas na página corretamente usando a biblioteca de formatos de data.

Peter Mortensen
fonte
26
Isso pode ser interessante: hanselman.com/blog/…
citronas
6
O formato /Date(...)/ é específico ao formato JSON Date da Microsoft - não faz parte de nenhum padrão, e o JSON, proveniente de Javascript, possui um padrão: O formato ISO Javascript especifica: stackoverflow.com/a / 15952652/176877 Portanto, esta pergunta é específica ao formato de data JSON da Microsoft. Eu modifiquei o título para esclarecer isso.
22614 Chris Moschini
15
Você está brincando! A Microsoft marcou seu próprio giro no JSON! e em datas !! Quando eles vão aprender!
Nick.McDermaid
Use o Newtonsoft JSON no lado .NET e para ter bons valores digitados no lado JS, basta usar: github.com/RickStrahl/json.date-extensions #
baHI
Você poderia usar JSON ++ em vez de JSON. JSON ++ é o mesmo que JSON, mas com suporte para tipos de JavaScript como Date.
Brillout 14/11/19

Respostas:

1688

eval()não é necessário. Isso funcionará bem:

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

A substr()função retira a /Date(peça, e a parseInt()função obtém o número inteiro e ignora o )/no final. O número resultante é passado para o Dateconstrutor.


Eu intencionalmente deixei de fora a raiz (o segundo argumento para parseInt); veja meu comentário abaixo .

Além disso, concordo totalmente com o comentário de Rory : as datas ISO-8601 são preferidas a esse formato antigo - portanto, esse formato geralmente não deve ser usado para novos desenvolvimentos. Veja a excelente biblioteca Json.NET para uma ótima alternativa que serializa datas usando o formato ISO-8601.

Para datas JSON no formato ISO-8601, basta passar a string para o Dateconstrutor:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Roy Tinker
fonte
4
@Broam: Ambos os métodos (a função de substituição e esta resposta) teriam que mudar se o MS alterar o formato.
Roy Tinker
23
Você poderia atualizá-lo com o radix var date = new Date (parseInt (jsonDate.substr (6), 10));
James Kyburz
6
@ JamesKyburz: Toda regra tem exceções, e acho que é quando uma exceção se aplica. Os números de data JSON do .NET nunca têm um "0" inicial, para que possamos deixar de fora o radix com segurança.
Roy Tinker
22
Vale a pena notar que esse formato de data é muito ruim e a mudança geral é para datas no formato ISO-8601 em JSON. Veja hanselman.com/blog/…
Rory
4
Essa abordagem falha ao considerar o fuso horário e, portanto, pode causar sérios problemas quando o servidor e os usuários estão em fusos horários diferentes. Eu postei uma resposta abaixo que explica uma maneira muito rápida e fácil de lidar com ele em WCF e Javascript lados: stackoverflow.com/a/10743718/51061
Scott Willeke
135

Você pode usar isso para obter uma data em JSON:

var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));

E então você pode usar um script JavaScript Date Format (1,2 KB quando minificado e compactado com gzip) para exibi-lo como desejar.

Panos
fonte
7
Não há nada errado com a linha, a sequência é \ //. A primeira barra é escapada, portanto não conta como um comentário. É o seu editor enganando você, a linha funcionará bem.
27610 andreialecu
152
@rball, absurdo:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
eyelidlessness
39
pst estava correto, é possível fazer isso de várias maneiras sem 'eval'. Crockford diz que 'eval Is Evil' é menos legível e menos seguro; além disso, ele pode sugerir que é menos eficiente e mais perigoso porque atinge o compilador javascript.
Mark Rogers
13
@Edy: new Functioné quase tão ruim quanto eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel
5
@ Hey: Essa é outra forma de avaliação, e é tão "má". Analisar a cadeia em vez (ver minha resposta abaixo)
Roy Tinker
98

Para quem usa o Newtonsoft Json.NET , leia como fazê-lo via JSON nativo no IE8, Firefox 3.5 e Json.NET .

Também é útil a documentação sobre como alterar o formato das datas escritas pelo Json.NET: Serializando datas com o Json.NET

Para aqueles que são preguiçosos, aqui estão os passos rápidos. Como o JSON tem uma implementação frouxa de DateTime, você precisa usar o IsoDateTimeConverter(). Observe que, desde o Json.NET 4.5, o formato padrão da data é ISO, portanto o código abaixo não é necessário.

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

O JSON será apresentado como

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

Por fim, algum JavaScript para converter a data ISO em uma 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;
}

Eu usei assim

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
Jason Jong
fonte
6
O construtor JavaScript Date pode analisar a sequência para você:new Date("2009-04-12T20:44:55")
David Hogue
5
Aviso - Os formatos e a análise do construtor Date () não são padrão antes do ECMAScript 6. Por exemplo, o IE 9 trata a data em que você fornece o construtor como um horário local, mesmo que esteja no IS0-8601, que está implícito como UCT em qualquer outro lugar. Não confie no construtor de datas se você suportar navegadores mais antigos. codeofmatt.com/2013/06/07/…
DanO 22/09
O envio de uma data que não seja UTC, mais cedo ou mais tarde, causará problemas.
21416 Tymtam
Um pouco atrasado para a festa aqui, mas o que seria (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; representar neste contexto?
yanant 4/03
@yanant - o +a[1]etc representa as partes da matriz do regex e a +converteria em um número, então +a[1]é igual a 2009etc. Aqui está a divisão da matriz: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong
67

O exemplo original:

/Date(1224043200000)/  

não reflete a formatação usada pelo WCF ao enviar datas via WCF REST usando a serialização JSON integrada. (pelo menos no .NET 3.5, SP1)

Eu achei a resposta aqui útil, mas é necessária uma pequena edição no regex, pois parece que o deslocamento GMT do fuso horário está sendo anexado ao número retornado (desde 1970) no WCF JSON.

Em um serviço WCF, tenho:

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

ApptVisitLinkInfo é definido simplesmente:

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

Quando "Field2" é retornado como Json do serviço, o valor é:

/Date(1224043200000-0600)/

Observe o deslocamento do fuso horário incluído como parte do valor.

O regex modificado:

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

É um pouco mais ansioso e pega tudo entre parênteses, não apenas o primeiro número. O tempo resultante desde 1970, mais o deslocamento do fuso horário podem ser alimentados no eval para obter um objeto de data.

A linha resultante de JavaScript para a substituição é:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Aaron
fonte
10
isso está errado, a nova data (1224043200000-0600) subtrairá apenas 600 da data, neste caso, 600 milissegundos, e não 6 horas como deveria.
Ariel
@ariel: Dê uma olhada no Javascript Date de milissegundos e fuso horário
Bergi
Eu acho que o deslocamento do fuso horário é incluído apenas se você tiver um fuso horário no objeto DateTime no .NET (que é o comportamento padrão). Se sua data estiver no UTC, use DateTime.SpecifyKind (date, DateTimeKind.UTC) e você obterá o valor UTC adequado quando ele serializar, sem deslocamento, que poderá ser convertido novamente no fuso horário do usuário, conforme necessário. Se estiver no horário local, use .ToUniversalTime () e ele será convertido para UTC e tenha o "Kind" já especificado para você.
Jvenema
em javascript -0100 será uma string binária, então tenha cuidado!
verbedr
Depois de converter a data do WCF para JS, que tal reverter. Você tem uma data como número inteiro (usando date.getTime ()) que deseja passar para o mesmo WCF?
NitinSingh
65

Não se repita - automatize a conversão de datas usando $.parseJSON()

As respostas à sua postagem fornecem a conversão manual de datas para datas JavaScript. Estendi o jQuery $.parseJSON()apenas um pouco, para poder analisar automaticamente as datas quando você o instruir. Ele processa datas formatadas em ASP.NET ( /Date(12348721342)/) e datas formatadas em ISO (2010-01-01T12.34.56.789Z ) suportadas por funções JSON nativas em navegadores (e bibliotecas como json2.js).

De qualquer forma. Se você não quiser repetir seu código de conversão de datas repetidamente, sugiro que você leia esta postagem do blog e obtenha o código que facilitará sua vida.

Robert Koritnik
fonte
61

Se você diz em JavaScript,

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

você verá que é a data correta e pode usá-la em qualquer lugar do código JavaScript com qualquer estrutura.

John Boker
fonte
3
Isso é o que eu pensaria também, exceto que acaba sendo: var thedate = / Date (1224043200000) /; pelo menos para mim ...
rball 03/12
2
Data () e Data (1224043200000) dão o mesmo resultado no Chrome e no Firefox. Não tenho certeza se isso funcionou em navegadores antigos, mas esta resposta não funciona em navegadores agora.
James
@ James, Sim, está dando a data atual do navegador. :(
vissu
9
Você precisa escrevê-lo como "nova data (1224043200000)".
BrainSlugs83
60

Clique aqui para conferir a demonstração

JavaScript / jQuery

var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
            (
                 parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
            );
var dat = value.getMonth() +
                         1 +
                       "/" +
           value.getDate() +
                       "/" +
       value.getFullYear();

Resultado - "15/10/2008"

user2007801
fonte
Apenas uma melhoria para o método acima. função formatearFecha (fec) {var value = new Date (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, '')))); var mes = value.getMonth (); var dia = valor.getDate (); var data = dia + "/" + mes + "/" + valor.getFullYear (); if (dia <10) data = data.substr (0, 0) + '0' + dia + date.substr (1); if (mes <10) date = date.substr (0, 3) + '0' + mes + date.substr (4); data de retorno;} data formatada para Abraços!
Matias
38

Atualizada

Temos uma biblioteca de interface do usuário interna que precisa lidar com o formato JSON interno do ASP.NET da Microsoft, como /Date(msecs)/perguntado aqui originalmente, e com o formato de data da maioria dos JSON, incluindo o JSON.NET, como 2014-06-22T00:00:00.0. Além disso, precisamos lidar com a incapacidade do oldIE de lidar com qualquer coisa, exceto três casas decimais .

Primeiro detectamos que tipo de data estamos consumindo, analisamos em um JavaScript normal Date objeto , em seguida, formata-o.

1) Detectar o formato Microsoft Date

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

2) Detectar formato de 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) Analisar formato de data do MS:

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

4) Analise o formato da data ISO.

Temos pelo menos uma maneira de ter certeza de que estamos lidando com datas ISO padrão ou datas ISO modificadas para sempre ter três locais de milissegundos ( veja acima ), portanto, o código é diferente dependendo do ambiente.

4a) Analisar o formato padrão de data ISO, lidar com os problemas do 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) Analise o formato ISO com três casas decimais fixas de três milissegundos - muito mais fácil:

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

5) Formate-o:

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) Amarre tudo junto:

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

    return formatDate(d);
}

A resposta antiga abaixo é útil para vincular essa formatação de data à análise JSON do jQuery, para que você obtenha objetos Date em vez de strings, ou se ainda estiver preso no jQuery <1.5 de alguma forma.

Resposta antiga

Se você estiver usando a função Ajax do jQuery 1.4 com o ASP.NET MVC, poderá transformar todas as propriedades DateTime em objetos Date com:

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

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

No jQuery 1.5, você pode evitar a substituição parseJSONglobal do método usando a opção conversores na chamada Ajax.

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

Infelizmente, você precisa mudar para a rota de avaliação mais antiga para fazer com que as Datas analisem globalmente no local - caso contrário, é necessário convertê-las mais caso a caso, após a análise.

Chris Moschini
fonte
27

Não há um tipo de data interno no JSON . Parece o número de segundos / milissegundos de alguma época. Se você conhece a época, pode criar a data adicionando a quantidade certa de tempo.

johnstok
fonte
Isso está incorreto, o JSON usa datas Javascript, com informações adicionais de fuso horário - a época é igual à época da classe Date do javascript (por razões óbvias).
BrainSlugs83
3
@ BrainSlug83 - esta resposta fornece uma referência para a afirmação de que o JSON não tem um tipo de data interno. Se você não concordar, forneça uma referência alternativa. (Você não está pensando em uma estrutura específica que decidiu um formato de string para representar datas, não é? Isso não faz parte do padrão JSON, na verdade não poderia ser porque impossibilitaria a inclusão de uma string que não seja deveria ser tomado como uma data, mas que acontece de ter um conjunto de caracteres que correspondem ao padrão de data).
nnnnnn
25

Também tive que procurar uma solução para esse problema e, finalmente, me deparei com o moment.js, que é uma boa biblioteca que pode analisar esse formato de data e muito mais.

var d = moment(yourdatestring)

Isso me salvou de dor de cabeça, então pensei em compartilhar com você. :)
Você pode encontrar mais algumas informações sobre isso aqui: http://momentjs.com/

Venemo
fonte
24

Acabei adicionando os "caracteres à expressão regular do Panos para nos livrarmos dos gerados pelo serializador da Microsoft ao escrever objetos em um script embutido:

Portanto, se você tem uma propriedade em seu código C # por trás, é algo como

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

E no seu aspx você tem

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

Você receberia algo como

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

Observe as aspas duplas.

Para obter isso em um formulário que eval deserialize corretamente, usei:

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

Eu uso Prototype e para usá-lo eu adicionei

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

No jQuery 1.5, desde que você tenha o json2.js para navegadores mais antigos, é possível desserializar todas as datas provenientes do Ajax da seguinte maneira:

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

Incluí uma lógica que supõe que você envie todas as datas do servidor como UTC (o que você deveria); o consumidor recebe um Dateobjeto JavaScript com o valor de ticks adequado para refletir isso. Ou seja, chamar getUTCHours()etc. na data retornará o mesmo valor que no servidor e chamargetHours() retornará o valor no fuso horário local do usuário, conforme determinado pelo navegador.

Isso não leva em conta o formato WCF com deslocamentos de fuso horário, embora isso seja relativamente fácil de adicionar.

Domenic
fonte
Apenas como uma observação: para que o código funcione, você deve criar o método beginWith do tipo string
Hugo Zapata
21

Usando o datepicker da interface do usuário do jQuery - realmente só faz sentido se você já estiver incluindo a interface do usuário do jQuery:

$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6)))); 

resultado:

15 de outubro de 2008

dominic
fonte
20

Não pense demais nisso. Como fizemos por décadas, passe um deslocamento numérico da época padrão de fato de 1 de janeiro de 1970 à meia-noite GMT / UTC / & c em número de segundos (ou milissegundos) desde essa época. JavaScript gosta, Java gosta, C gosta e a Internet gosta.

Xepoch
fonte
2
E pena que existem mais de 20 épocas para escolher. en.wikipedia.org/wiki/Epoch_(reference_date)
Jerther 30/10
Essa é a coisa legal dos padrões .
21718 Marc
18

Todas essas respostas têm uma coisa em comum: todas elas armazenam datas como um valor único (geralmente uma string).

Outra opção é aproveitar a estrutura inerente do JSON e representar uma data como lista de números:

{ "name":"Nick",
  "birthdate":[1968,6,9] }

Obviamente, você precisaria garantir que os dois lados da conversa concordassem com o formato (ano, mês, dia) e quais campos deveriam ser datas, ... mas isso tem a vantagem de evitar completamente a questão da data conversão para string. São todos os números - sem nenhuma string. Além disso, o uso da ordem: ano, mês, dia também permite a classificação correta por data.

Apenas pensando fora da caixa aqui - uma data JSON não precisa ser armazenada como uma string.

Outro bônus a fazer dessa maneira é que você pode selecionar (de maneira fácil e eficiente) todos os registros para um determinado ano ou mês, aproveitando a maneira como o CouchDB lida com consultas sobre valores de matriz.

Nick Perkins
fonte
Não é um formato padrão para datas em JSON, que é o formato RFC 3339.
gnasher729
@gnasher, isso seria bom, mas não é o caso. Não há referências da RFC 7159 a 3339 ou vice-versa. Não existe um formato de data JSON padrão de jure . Tudo o que resta são padrões de fato , cada um com prós / contras. Essa é a coisa legal dos padrões.
18718 Marc
17

Postagem em tópico impressionante:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Dan Beam
fonte
1
Boa ideia, mas e se um deslocamento de fuso horário for incluído? Melhor usar substr (6) nesse caso, em vez de fatia (6, -2) - veja minha resposta abaixo.
Roy Tinker
17

Apenas para adicionar outra abordagem aqui, a "abordagem de ticks" adotada pelo WCF é propensa a problemas com fusos horários, se você não for extremamente cuidadoso, como descrito aqui e em outros lugares. Portanto, agora estou usando o formato ISO 8601 que .NET e JavaScript suportam devidamente, incluindo compensações de fuso horário. Abaixo estão os detalhes:

No WCF / .NET:

Onde CreationDate é um System.DateTime; ToString ("o") está usando o especificador de formato de ida e volta do .NET que gera uma string de data compatível com ISO 8601

new MyInfo {
    CreationDate = r.CreationDate.ToString("o"),
};

Em JavaScript

Logo após recuperar o JSON, corrigi as datas para serem objetos JavaSript Date usando o construtor Date, que aceita uma string de data ISO 8601 ...

$.getJSON(
    "MyRestService.svc/myinfo",
    function (data) {
        $.each(data.myinfos, function (r) {
            this.CreatedOn = new Date(this.CreationDate);
        });
        // Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
       alert(data.myinfos[0].CreationDate.toLocaleString());
    }
)

Depois de ter uma data JavaScript, você pode usar todos os métodos Date, convenientes e confiáveis, como toDateString , toLocaleString , etc.

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

Existe outra opção sem usar a biblioteca jQuery?

blgnklc
fonte
Esta é uma nova pergunta e deve ser feita como sua própria pergunta e não incorporada aqui.
Spencer Sullivan
11

Isso também pode ajudá-lo.

 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();
    }
Ravi Mehta
fonte
10

Abaixo está uma solução bastante simples para analisar datas JSON. Use as funções abaixo conforme sua exigência. Você só precisa passar o formato JSON Data buscado como parâmetro para as funções abaixo:

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;
}
Umar Malik
fonte
10

Você também pode usar a biblioteca JavaScript moment.js , que é útil quando você planeja lidar com diferentes formatos localizados e executar outras operações com valores de datas:

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

Configurar a localização é tão fácil quanto adicionar arquivos de configuração (você os encontra em momentjs.com) ao seu projeto e configurar o idioma:

moment.lang('de');
martinoss
fonte
9

Recebo a data assim:

"/Date(1276290000000+0300)/"

Em alguns exemplos, a data está em formatos ligeiramente diferentes:

"/Date(12762900000000300)/"
"Date(1276290000000-0300)"

etc.

Então, eu vim com o seguinte RegExp:

/\/+Date\(([\d+]+)\)\/+/

e o código final é:

var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));

Espero que ajude.

Atualização: Encontrei este link da Microsoft: Como serializar datas com JSON?

Parece que é o que estamos procurando.

Michael Vashchinsky
fonte
1
As substituições do Regexp são lentas ... É muito mais rápido pegar a parte inteira usando substr (6) e passá-la para parseInt () - veja minha resposta abaixo.
Roy Tinker
Também ter um olhar para Javascript Data de milissegundos e fuso horário
Bergi
9

Verifique a data do padrão ISO; mais ou menos assim:

yyyy.MM.ddThh:mm

Torna-se 2008.11.20T22:18.

Thomas Hansen
fonte
De acordo com o esquema JSON, o formato "data e hora" corresponde ao RFC 3339, seção 5.6. Portanto, você deve escrever "aaaa-MM-ddTHH: mm: ssZ" para datas no GMT ou o Z será substituído por um fuso horário como + hh: mm.
precisa saber é o seguinte
O problema é que o WCF e outras serializações "antigas" do MS JSON não usam esse formato e isso deve ser levado em consideração.
21718 Marc
9

Isso é frustrante. Minha solução foi analisar o "/ e /" do valor gerado pelo JavaScriptSerializer do ASP.NET para que, embora o JSON possa não ter uma data literal, ele ainda seja interpretado pelo navegador como uma data, que é tudo o que realmente quer:{"myDate":Date(123456789)}

JavaScriptConverter personalizado para DateTime?

Devo enfatizar a precisão do comentário de Roy Tinker. Isso não é JSON legal. É um truque sujo no servidor para remover o problema antes que ele se torne um problema para JavaScript. Isso bloqueará um analisador JSON. Usei-o para decolar, mas não uso mais isso. No entanto, ainda sinto que a melhor resposta está em alterar a forma como o servidor formata a data, por exemplo, ISO, conforme mencionado em outro lugar.

StarTrekRedneck
fonte
2
Isso não é JSON legal. Só funcionará ao avaliar com um intérprete Javascript. Mas se você estiver usando um decodificador JSON, ele engasgará.
Roy Tinker
1
Acordado. E se eu estivesse lidando apenas com esses dados, não consideraria. Mas se eu estou lidando com um objeto de várias datas e outras propriedades, é mais fácil avaliar () a coisa toda do que escolher as propriedades uma por vez. No final, o problema principal é a falta de uma data JSON (legal). Até que isso exista, somos deixados para nossos hacks criativos.
StarTrekRedneck
8

Um post atrasado, mas para aqueles que pesquisaram este post.

Imagina isto:

    [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");
    }

Como você pode ver, estou utilizando o recurso do C # 3.0 para criar os genéricos "Auto". É um pouco preguiçoso, mas eu gosto e funciona. Apenas uma observação: o perfil é uma classe personalizada que criei para o meu projeto de aplicativo da web.

Ray Linder
fonte
portanto, toda vez que você adiciona uma nova função [Autorizar (Funções = "Recursos Humanos")], é necessário compilar e implantar? wow .... :)
Alex Nolasco
1
Se este for um serviço JSON, o redirecionamento parece errado. Eu retornaria um 404 não encontrado se a chave de entrada for tão inválida que não possa ser encontrada (e também 404 se ela realmente não for encontrada). Quando meus usuários não estão conectados, retorno 403 Proibido.
Richard Corfield
É um método "reutilizável". Por exemplo, se eu quiser obter dados do usuário de outra Visualização, posso obtê-los desde que forneça o ID. No entanto, se o ID não for fornecido, a página será redirecionada para uma lista de usuários (Índice) para selecionar um usuário. Solução simples necessária para o aplicativo, da mesma maneira que meu cérebro o preparou na época.
Raio Linder
8

Para sua informação, para quem usa Python no lado do servidor: datetime.datetime (). Ctime () retorna uma string que é nativamente analisável por "new Date ()". Ou seja, se você criar uma nova instância datetime.datetime (como datetime.datetime.now), a cadeia poderá ser incluída na cadeia JSON e, em seguida, essa cadeia poderá ser passada como o primeiro argumento para o construtor Date. Ainda não encontrei nenhuma exceção, mas também não a testei com rigor.

Kyle Alan Hale
fonte
8

Solução Mootools:

new Date(Date(result.AppendDts)).format('%x')

Requer mais mootools. Testado usando o mootools-1.2.3.1-more no Firefox 3.6.3 e IE 7.0.5730.13

Midhat
fonte
8
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];
在 路上
fonte
8

Adicione o plugin jQuery UI à sua página:

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

E se o .NET retornar ...

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

E então em JavaScript ...

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