¿Cómo formateo una fecha de Microsoft JSON?

2001

Estoy tomando mi primer crack en Ajax con jQuery. Estoy obteniendo mis datos en mi página, pero tengo algunos problemas con los datos JSON que se devuelven para los tipos de datos de fecha. Básicamente, estoy obteniendo una cadena de nuevo que se ve así:

/Date(1224043200000)/

De alguien totalmente nuevo en JSON: ¿cómo formateo esto a un formato de fecha corta? ¿Debería manejarse esto en algún lugar del código jQuery? He intentado jQuery.UI.datepickerusar el complemento $.datepicker.formatDate()sin ningún éxito.

FYI: Aquí está la solución que se me ocurrió usando una combinación de las respuestas aquí:

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

Esta solución obtuvo mi objeto del método de devolución de llamada y mostró las fechas en la página correctamente utilizando la biblioteca de formato de fecha.

Peter Mortensen
fuente
26
Esto puede ser interesante: hanselman.com/blog/…
citronas
66
El formato /Date(...)/ es específico del formato de fecha JSON incorporado de Microsoft: no forma parte de ningún estándar, y JSON, que proviene de Javascript, tiene un estándar: el formato ISO Javascript especifica: stackoverflow.com/a / 15952652/176877 Entonces, esta pregunta es específica del formato de fecha JSON de Microsoft. Modifiqué el título para aclarar esto.
Chris Moschini
15
Estás bromeando! ¡Microsoft ha estampado su propio giro en JSON! y en fechas !! ¿Cuándo van a aprender?
Nick.McDermaid
Use Newtonsoft JSON en el lado .NET y para tener buenos valores escritos en el lado JS, solo use: github.com/RickStrahl/json.date-extensions
baHI
Podrías usar JSON ++ en lugar de JSON. JSON ++ es lo mismo que JSON pero con soporte para tipos de JavaScript como Date.
brillante

Respuestas:

1688

eval()no es necesario. Esto funcionará bien:

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

La substr()función saca la /Date(parte, y la parseInt()función obtiene el número entero e ignora el )/al final. El número resultante se pasa al Dateconstructor.


He omitido intencionalmente la raíz (el segundo argumento para parseInt); mira mi comentario a continuación .

Además, estoy completamente de acuerdo con el comentario de Rory : las fechas ISO-8601 son preferibles a este formato antiguo, por lo que este formato generalmente no debe usarse para un nuevo desarrollo. Vea la excelente biblioteca Json.NET para una gran alternativa que serializa fechas usando el formato ISO-8601.

Para fechas JSON con formato ISO-8601, simplemente pase la cadena al Dateconstructor:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Roy Tinker
fuente
44
@Broam: Ambos métodos (la función de reemplazo y esta respuesta) tendrían que cambiar si MS cambia el formato.
Roy Tinker
23
¿Podría actualizarlo con radix var date = new Date (parseInt (jsonDate.substr (6), 10));
James Kyburz el
66
@JamesKyburz: cada regla tiene excepciones, y creo que es cuando se aplica una excepción. Los números de fecha JSON de .NET nunca tienen un "0" inicial, por lo que podemos omitir la raíz de forma segura.
Roy Tinker
22
Vale la pena señalar que este formato de fecha es bastante malo y el movimiento general es a las fechas con formato ISO-8601 en JSON. Ver hanselman.com/blog/…
Rory
44
Este enfoque no tiene en cuenta la zona horaria, por lo que puede causar serios problemas cuando el servidor y los usuarios se encuentran en diferentes zonas horarias. Publiqué una respuesta a continuación que explica una manera muy rápida y fácil de manejarlo en WCF y Javascript: stackoverflow.com/a/10743718/51061
Scott Willeke
135

Puede usar esto para obtener una fecha de JSON:

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

Y luego puede usar un script de formato de fecha de JavaScript (1.2 KB cuando está minimizado y comprimido) para mostrarlo como desee.

Panos
fuente
77
No hay nada malo con la línea, la secuencia es \ //. Se escapa la primera barra oblicua, por lo que no cuenta como un comentario. Es tu editor el que te está engañando, la línea funcionará bien.
andreialecu
152
@rball, sin sentido:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
párpado
39
pst era correcto, es posible hacer esto de varias maneras sin 'evaluar'. Crockford dice que 'eval Is Evil' porque es menos legible y menos seguro, además puede implicar que es menos eficiente y más peligroso porque golpea el compilador de JavaScript.
Mark Rogers
13
@Edy: new Functiones casi tan malo como eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel
55
@Edy: Esa es otra forma de evaluación, y es tan 'malvada'. Analice la cadena en su lugar (vea mi respuesta a continuación)
Roy Tinker
98

Para aquellos que usan Newtonsoft Json.NET , lea sobre cómo hacerlo a través de Native JSON en IE8, Firefox 3.5 más Json.NET .

También es útil la documentación sobre cómo cambiar el formato de las fechas escritas por Json.NET: Serializar fechas con Json.NET

Para aquellos que son demasiado vagos, estos son los pasos rápidos. Como JSON tiene una implementación de DateTime suelta, debe usar el IsoDateTimeConverter(). Tenga en cuenta que desde Json.NET 4.5 el formato de fecha predeterminado es ISO, por lo que no se necesita el siguiente código.

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

El JSON aparecerá como

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

Finalmente, algunos JavaScript para convertir la fecha ISO en una fecha 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;
}

Lo usé asi

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
Jason Jong
fuente
66
El constructor de JavaScript Date puede analizar la cadena por usted:new Date("2009-04-12T20:44:55")
David Hogue
55
Advertencia: los formatos y análisis de fecha () del constructor no son estándar antes de ECMAScript 6. Por ejemplo, IE 9 trata la fecha que le da al constructor como una hora local, incluso si está en IS0-8601, lo cual está implícito como UCT en cualquier otro lugar. No confíe en el constructor de fechas si admite navegadores más antiguos. codeofmatt.com/2013/06/07/…
DanO
Enviar una fecha que no sea UTC tarde o temprano lo meterá en problemas.
tymtam
Un poco tarde para la fiesta aquí, pero qué (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; representar en este contexto?
Yanant
@yanant: el +a[1]etc. representa las piezas de la matriz de la expresión regular y la +convertiría en un número, por lo que +a[1]es igual, 2009etc. Aquí está el desglose de la matriz: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong
67

El ejemplo original:

/Date(1224043200000)/  

no refleja el formato utilizado por WCF al enviar fechas a través de WCF REST utilizando la serialización JSON incorporada. (al menos en .NET 3.5, SP1)

La respuesta aquí me pareció útil, pero se requiere una pequeña edición de la expresión regular, ya que parece que el desplazamiento GMT de la zona horaria se agrega al número devuelto (desde 1970) en WCF JSON.

En un servicio WCF tengo:

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

ApptVisitLinkInfo se define simplemente:

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

Cuando se devuelve "Field2" como Json del servicio, el valor es:

/Date(1224043200000-0600)/

Observe el desplazamiento de la zona horaria incluido como parte del valor.

La expresión regular modificada:

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

Es un poco más ansioso y toma todo entre los padres, no solo el primer número. El tiempo resultante desde 1970, más el desplazamiento de la zona horaria, todos se pueden alimentar a la evaluación para obtener un objeto de fecha.

La línea resultante de JavaScript para el reemplazo es:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Aaron
fuente
10
esto está mal, la nueva Fecha (1224043200000-0600) solo restará 600 de la fecha, en este caso 600 milisegundos, no 6 horas como debería.
ariel
@ariel: Echa un vistazo a la fecha de Javascript de milisegundos y zona horaria
Bergi
Creo que el desplazamiento de la zona horaria solo se incluye si tiene una zona horaria en el objeto DateTime en .NET (que es el comportamiento predeterminado). Si su fecha está en UTC, use DateTime.SpecifyKind (date, DateTimeKind.UTC) y obtendrá el valor UTC adecuado cuando se serialice, sin compensación, que luego puede volver a convertir a la zona horaria del usuario según sea necesario. Si es en hora local, use .ToUniversalTime () y se convertirá a UTC, y tendrá el "Tipo" ya especificado para usted.
jvenema
en javascript -0100 será una cadena binaria, ¡así que ten cuidado!
verbedr
una vez que haya convertido la fecha de WCF a JS, ¿qué tal si se invierte? ¿Tienes una fecha como entero (usando date.getTime ()) que deseas pasar al mismo WCF?
NitinSingh
65

No te repitas: automatiza la conversión de fechas usando $.parseJSON()

Las respuestas a su publicación proporcionan conversión manual de fecha a fechas de JavaScript. He extendido jQuery $.parseJSON()solo un poco, por lo que puede analizar automáticamente las fechas cuando se lo indique. Procesa las fechas con formato ASP.NET ( /Date(12348721342)/) así como las fechas con formato ISO ( 2010-01-01T12.34.56.789Z) que son compatibles con las funciones nativas de JSON en los navegadores (y bibliotecas como json2.js).

De todas formas. Si no desea repetir su código de conversión de fecha una y otra vez, le sugiero que lea esta publicación de blog y obtenga el código que le facilitará la vida.

Robert Koritnik
fuente
61

Si dices en JavaScript,

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

verá que es la fecha correcta, y puede usarla en cualquier parte del código JavaScript con cualquier marco.

John Boker
fuente
3
Eso es lo que habría pensado también, excepto que termina siendo: var thedate = / Date (1224043200000) /; al menos para mí ...
rball
2
Fecha () y Fecha (1224043200000) dan el mismo resultado en Chrome y Firefox. No estoy seguro si esto funcionó en los navegadores antiguos, pero esta respuesta no funciona en los navegadores ahora.
James
@ James, sí, está dando la fecha actual del navegador. :(
vissu
99
Debe escribirlo como "nueva Fecha (1224043200000)".
BrainSlugs83
60

Haga clic aquí para ver la demostración

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"

usuario2007801
fuente
Solo una mejora para el método anterior. function formatearFecha (fec) {var value = new Date (parseInt (fec.replace (/ (^. * () | ([+ -]. * $) / g, ''))); var mes = value.getMonth (); var dia = value.getDate (); var date = dia + "/" + mes + "/" + value.getFullYear (); if (dia <10) date = date.substr (0, 0) + '0' + dia + date.substr (1); if (mes <10) date = date.substr (0, 3) + '0' + mes + date.substr (4); fecha de retorno;} fecha formateada para ddMMyyyy. ¡Salud!
Matias
38

Actualizado

Tenemos una biblioteca de interfaz de usuario interna que tiene que hacer frente tanto al formato JSON incorporado de ASP.NET de Microsoft, como /Date(msecs)/, al que se le preguntó aquí originalmente, como a la mayoría de los formatos de fecha de JSON, incluidos JSON.NET 2014-06-22T00:00:00.0. Además, debemos hacer frente a la incapacidad de oldIE para hacer frente a cualquier cosa que no sean 3 decimales .

Primero detectamos qué tipo de fecha estamos consumiendo, lo analizamos en un Dateobjeto JavaScript normal y luego lo formateamos.

1) Detectar formato de fecha de Microsoft

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

2) Detectar formato de fecha 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 de fecha Parse MS:

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

4) Analizar el formato de fecha ISO.

Al menos tenemos una manera de asegurarnos de que estamos tratando con fechas ISO estándar o fechas ISO modificadas para tener siempre tres milisegundos ( ver arriba ), por lo que el código es diferente dependiendo del entorno.

4a) Analizar el formato de fecha ISO estándar, hacer frente a los problemas de 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) Analizar el formato ISO con un decimal fijo de tres milisegundos, mucho más fácil:

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

5) Formatearlo:

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) Ate todo 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);
}

La respuesta anterior a continuación es útil para vincular este formato de fecha al análisis JSON de jQuery para que obtenga objetos de fecha en lugar de cadenas, o si todavía está atascado en jQuery <1.5 de alguna manera.

Vieja respuesta

Si está utilizando la función Ajax de jQuery 1.4 con ASP.NET MVC, puede convertir todas las propiedades de DateTime en objetos Date con:

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

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

En jQuery 1.5 puede evitar anular el parseJSONmétodo globalmente utilizando la opción de convertidores en la llamada Ajax.

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

Desafortunadamente, debe cambiar a la ruta de evaluación más antigua para que las fechas se analicen globalmente en el lugar; de lo contrario, debe convertirlas caso por caso después del análisis.

Chris Moschini
fuente
27

No hay un tipo de fecha incorporado en JSON . Esto se parece a la cantidad de segundos / milisegundos de alguna época. Si conoce la época, puede crear la fecha agregando la cantidad de tiempo correcta.

johnstok
fuente
Eso es incorrecto, JSON usa fechas de Javascript, con información de zona horaria agregada: la época es la misma que la época de la clase Fecha de JavaScript (por razones obvias).
BrainSlugs83
3
@ BrainSlug83: esta respuesta proporciona una referencia para la afirmación de que JSON no tiene un tipo de fecha incorporado. Si no está de acuerdo, proporcione una referencia alternativa. (No está pensando en un marco específico que haya decidido un formato de cadena para representar fechas, ¿verdad? Eso no es parte del estándar JSON, de hecho, no podría ser porque haría imposible incluir una cadena que no sea se supone que debe tomarse como una fecha, pero eso tiene un conjunto de caracteres que coinciden con el patrón de fecha.)
nnnnnn
25

También tuve que buscar una solución a este problema y finalmente encontré moment.js, que es una buena biblioteca que puede analizar este formato de fecha y muchos más.

var d = moment(yourdatestring)

Me ahorró un poco de dolor de cabeza, así que pensé en compartirlo contigo. :)
Puedes encontrar más información al respecto aquí: http://momentjs.com/

Venemo
fuente
24

Terminé agregando los "caracteres en la expresión regular de Panos para deshacerme de los generados por el serializador de Microsoft para cuando se escriben objetos en un script en línea:

Entonces, si tiene una propiedad en su código C # detrás, es algo así como

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

Y en tu aspx tienes

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

Obtendrías algo como

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

Observe las comillas dobles.

Para obtener esto en una forma que eval deserialice correctamente, utilicé:

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

Yo uso Prototype y para usarlo agregué

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

En jQuery 1.5, siempre que tenga json2.js para cubrir los navegadores más antiguos, puede deserializar todas las fechas procedentes de Ajax de la siguiente manera:

(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í lógica que asume que envías todas las fechas desde el servidor como UTC (que deberías); el consumidor obtiene un Dateobjeto JavaScript que tiene el valor de ticks adecuado para reflejar esto Es decir, las llamadas getUTCHours(), etc. en la fecha devolverán el mismo valor que en el servidor, y las llamadas getHours()devolverán el valor en la zona horaria local del usuario según lo determine su navegador.

Esto no tiene en cuenta el formato WCF con las compensaciones de zona horaria, aunque eso sería relativamente fácil de agregar.

Domenic
fuente
Solo como una nota: para que el código funcione, debe crear los inicios con el método del tipo de cadena
Hugo Zapata
21

Usar el jQuery UI datepicker: realmente solo tiene sentido si ya está incluyendo jQuery UI:

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

salida:

15 de octubre de 2008

dominic
fuente
20

No pienses demasiado en esto. Como lo hemos hecho durante décadas, pase un desplazamiento numérico de la época estándar de facto del 1 de enero de 1970 a la medianoche GMT / UTC / & c en número de segundos (o milisegundos) desde esta época. A JavaScript le gusta, a Java le gusta, a C le gusta e Internet le gusta.

Xepoch
fuente
2
Y lástima que haya más de 20 épocas para elegir. en.wikipedia.org/wiki/Epoch_(reference_date)
Jerther
Eso es lo bueno de los estándares .
Marc L.
18

Cada una de estas respuestas tiene una cosa en común: todas almacenan las fechas como un valor único (generalmente una cadena).

Otra opción es aprovechar la estructura inherente de JSON y representar una fecha como una lista de números:

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

Por supuesto, deberá asegurarse de que ambos extremos de la conversación coincidan en el formato (año, mes, día) y qué campos deben ser fechas, pero tiene la ventaja de evitar por completo el problema de la fecha. -conversión a cadena. Son todos números, sin condiciones. Además, el uso del orden: año, mes, día también permite una clasificación adecuada por fecha.

Simplemente pensando fuera de la caja aquí: una fecha JSON no tiene que almacenarse como una cadena.

Otra ventaja de hacerlo de esta manera es que puede seleccionar fácilmente (y de manera eficiente) todos los registros para un año o mes dado al aprovechar la forma en que CouchDB maneja las consultas sobre los valores de la matriz.

Nick Perkins
fuente
No es un formato estándar para las fechas en JSON, que es el formato RFC 3339.
gnasher729
@gnasher, eso sería bueno, pero no es el caso. No hay referencias de RFC 7159 a 3339 o viceversa. No existe un formato de fecha JSON estándar de jure . Todo lo que queda son estándares de facto , cada uno de los cuales tiene pros / contras. Eso es lo bueno de los estándares.
Marc L.
17

Publicando en hilo impresionante:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Dan Beam
fuente
1
Buena idea, pero ¿qué pasa si se incluye un desplazamiento de zona horaria? Es mejor usar substr (6) en ese caso en lugar de cortar (6, -2); vea mi respuesta a continuación.
Roy Tinker
17

Solo para agregar otro enfoque aquí, el "enfoque de ticks" que adopta WCF es propenso a problemas con las zonas horarias si no es extremadamente cuidadoso como se describe aquí y en otros lugares. Así que ahora estoy usando el formato ISO 8601 que tanto .NET como JavaScript soportan debidamente que incluye compensaciones de zona horaria. Debajo están los detalles:

En WCF / .NET:

Donde CreationDate es un System.DateTime; ToString ("o") está utilizando el especificador de formato de ida y vuelta de .NET que genera una cadena de fecha compatible con ISO 8601

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

En JavaScript

Justo después de recuperar el JSON, voy a arreglar las fechas para que sean objetos de fecha JavaSript usando el constructor de fecha que acepta una cadena de fecha 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());
    }
)

Una vez que tenga una fecha de JavaScript, puede usar todos los métodos de Fecha convenientes y confiables como toDateString , toLocaleString , etc.

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

¿Hay otra opción sin usar la biblioteca jQuery?

blgnklc
fuente
Esta es una pregunta nueva y debe hacerse como una pregunta propia y no incrustada aquí.
Spencer Sullivan
11

Esto también puede ayudarlo.

 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
fuente
10

A continuación se muestra una solución bastante simple para analizar las fechas JSON. Utilice las siguientes funciones según sus requisitos. Solo necesita pasar el formato JSON Date obtenido como parámetro a las siguientes funciones:

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
fuente
10

También puede usar la biblioteca de JavaScript moment.js , que es útil cuando planea manejar diferentes formatos localizados y realizar otras operaciones con valores de fechas:

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 la localización es tan fácil como agregar archivos de configuración (los obtienes en momentjs.com) a tu proyecto y configurar el idioma:

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

Me sale la fecha así:

"/Date(1276290000000+0300)/"

En algunos ejemplos, la fecha está en formatos ligeramente diferentes:

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

etc.

Entonces se me ocurrió el siguiente RegExp:

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

y el código final es:

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

Espero eso ayude.

Actualización: Encontré este enlace de Microsoft: ¿Cómo serializo las fechas con JSON?

Este parece ser el que todos estamos buscando.

revs Michael Vashchinsky
fuente
1
Los reemplazos de expresiones regulares son lentos ... Es mucho más rápido agarrar la porción entera usando substr (6) y pasarla a parseInt () - vea mi respuesta a continuación.
Roy Tinker
También eche un vistazo a la Fecha Javascript de milisegundos y zona horaria
Bergi
9

Verifique la fecha estándar ISO; algo así como esto:

yyyy.MM.ddThh:mm

Se hace 2008.11.20T22:18.

Thomas Hansen
fuente
Según el esquema JSON, el formato "fecha-hora" corresponde a RFC 3339, sección 5.6. Por lo tanto, debe escribir "aaaa-MM-ddTHH: mm: ssZ" para las fechas en GMT, o la Z reemplazada por una zona horaria como + hh: mm.
gnasher729
El problema es que WCF y otras serializaciones de MS JSON "antiguas" no usan este formato, y eso debe tenerse en cuenta.
Marc L.
9

Esto es frustrante. Mi solución fue analizar el "/ y /" del valor generado por el JavaScriptSerializer de ASP.NET para que, aunque JSON no tenga una fecha literal, el navegador lo interprete como una fecha, que es lo que realmente realmente querer:{"myDate":Date(123456789)}

JavaScriptConverter personalizado para DateTime?

Debo enfatizar la precisión del comentario de Roy Tinker. Esto no es legal JSON. Es un truco sucio y sucio en el servidor para eliminar el problema antes de que se convierta en un problema para JavaScript. Se ahogará un analizador JSON. Lo usé para despegar, pero ya no lo uso. Sin embargo, todavía siento que la mejor respuesta radica en cambiar la forma en que el servidor formatea la fecha, por ejemplo, ISO como se menciona en otra parte.

StarTrekRedneck
fuente
2
Eso no es legal JSON. Solo funcionará cuando evalúe con un intérprete de Javascript. Pero si está utilizando un decodificador JSON, se ahogará.
Roy Tinker
1
Convenido. Y si solo estuviera tratando con este dato, no lo consideraría. Pero si estoy tratando con un objeto de varias fechas y otras propiedades, es más fácil evaluar todo () que elegir las propiedades de una en una. Al final, el problema raíz es la falta de una fecha JSON (legal). Hasta que eso exista, nos quedamos con nuestros trucos creativos.
StarTrekRedneck
8

Una publicación tardía, pero para aquellos que buscaron esta publicación.

Imagina esto:

    [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 puede ver, estoy utilizando la función de C # 3.0 para crear los genéricos "Auto". Es un poco vago, pero me gusta y funciona. Solo una nota: Profile es una clase personalizada que he creado para mi proyecto de aplicación web.

Ray Linder
fuente
así que cada vez que agrega un nuevo rol [Autorizar (Roles = "Recursos humanos")], ¿tiene que compilar e implementar? wow .... :)
Alex Nolasco
1
Si este es un servicio JSON, entonces la redirección parece incorrecta. Devolvería un 404 No encontrado si la clave de entrada es tan inválida que posiblemente no se pueda encontrar (y también 404 si realmente no se encuentra). Cuando mis usuarios no han iniciado sesión, devuelvo 403 Prohibido.
Richard Corfield
Es un método "reutilizable". Por ejemplo, si quisiera obtener datos de usuario de otra Vista, puedo obtenerlos siempre que proporcione el Id. Sin embargo, si no se proporciona el Id, la página redirige a una lista de usuarios (Índice) para seleccionar un usuario. Se necesita una solución simple para la aplicación, tal como mi cerebro la preparó en ese momento.
Ray Linder
8

Para su información, para cualquiera que use Python en el lado del servidor: datetime.datetime (). Ctime () devuelve una cadena que se puede analizar de forma nativa por "new Date ()". Es decir, si crea una nueva instancia de datetime.datetime (como con datetime.datetime.now), la cadena se puede incluir en la cadena JSON, y luego esa cadena se puede pasar como el primer argumento para el constructor Fecha. Todavía no he encontrado ninguna excepción, pero tampoco la he probado demasiado rigurosamente.

Kyle Alan Hale
fuente
8

Solución de Mootools:

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

Requiere mootools-more. Probado con mootools-1.2.3.1-more en Firefox 3.6.3 e IE 7.0.5730.13

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

Agregue el complemento jQuery UI en su página:

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

¿Qué pasa si .NET regresa ...

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

Y luego en JavaScript ...

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