Comment formater une date Microsoft JSON?

2001

Je prends ma première fissure à Ajax avec jQuery. Je reçois mes données sur ma page, mais j'ai des problèmes avec les données JSON qui sont renvoyées pour les types de données Date. Fondamentalement, je reçois une chaîne qui ressemble à ceci:

/Date(1224043200000)/

De quelqu'un totalement nouveau sur JSON - Comment puis-je formater cela en un format de date courte? Cela devrait-il être géré quelque part dans le code jQuery? J'ai essayé le jQuery.UI.datepickerplugin $.datepicker.formatDate()sans succès.

FYI: Voici la solution que j'ai trouvée en utilisant une combinaison des réponses ici:

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

Cette solution a obtenu mon objet de la méthode de rappel et affiché correctement les dates sur la page en utilisant la bibliothèque de format de date.

Peter Mortensen
la source
26
Cela pourrait être intéressant: hanselman.com/blog/…
citronas
6
Le format /Date(...)/ est spécifique au format de date JSON intégré de Microsoft - il ne fait partie d'aucune norme, et JSON, provenant de Javascript, a une norme: Le format ISO Javascript spécifie: stackoverflow.com/a / 15952652/176877 Donc, cette question est spécifique au format de date JSON de Microsoft. J'ai modifié le titre pour clarifier cela.
Chris Moschini
15
Vous plaisantez! Microsoft a marqué son propre tour sur JSON! et aux dates !! Quand apprendront-ils!
Nick.McDermaid
Utilisez Newtonsoft JSON du côté .NET et pour avoir de belles valeurs tapées du côté JS, utilisez simplement: github.com/RickStrahl/json.date-extensions
baHI
Vous pouvez utiliser JSON ++ au lieu de JSON. JSON ++ est le même que JSON mais avec la prise en charge des types JavaScript tels que Date.
brillout

Réponses:

1688

eval()n'est pas nécessaire. Cela fonctionnera bien:

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

La substr()fonction supprime la /Date(partie, et la parseInt()fonction obtient l'entier et ignore le )/à la fin. Le nombre résultant est transmis au Dateconstructeur.


J'ai intentionnellement omis la radix (le deuxième argument de parseInt); voir mon commentaire ci-dessous .

De plus, je suis entièrement d'accord avec le commentaire de Rory : les dates ISO-8601 sont préférées à cet ancien format - donc ce format ne devrait généralement pas être utilisé pour de nouveaux développements. Voir l'excellente bibliothèque Json.NET pour une excellente alternative qui sérialise les dates en utilisant le format ISO-8601.

Pour les dates JSON au format ISO-8601, passez simplement la chaîne dans le Dateconstructeur:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
Roy Tinker
la source
4
@Broam: Les deux méthodes (la fonction de remplacement et cette réponse) devraient changer si MS change le format.
Roy Tinker
23
Pourriez-vous le mettre à jour avec le radix var date = new Date (parseInt (jsonDate.substr (6), 10));
James Kyburz
6
@JamesKyburz: Chaque règle a des exceptions, et je pense que c'est quand une exception s'applique. Les numéros de date JSON de .NET n'ont jamais de "0" de tête, nous pouvons donc ignorer la radix en toute sécurité.
Roy Tinker
22
Il convient de noter que ce format de date est assez mauvais et que la tendance générale est aux dates formatées ISO-8601 en JSON. Voir hanselman.com/blog/…
Rory
4
Cette approche ne prend pas en compte le fuseau horaire et peut donc entraîner de graves problèmes lorsque votre serveur et vos utilisateurs se trouvent dans des fuseaux horaires différents. J'ai posté une réponse ci-dessous qui explique un moyen très rapide et facile de le gérer côté WCF et Javascript: stackoverflow.com/a/10743718/51061
Scott Willeke
135

Vous pouvez l'utiliser pour obtenir une date de JSON:

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

Et puis vous pouvez utiliser un script JavaScript Date Format (1,2 Ko lorsqu'il est minifié et compressé) pour l'afficher comme vous le souhaitez.

Panos
la source
7
Il n'y a rien de mal avec la ligne, la séquence est \ //. La première barre oblique est échappée et ne compte donc pas comme un commentaire. C'est votre éditeur qui vous trompe, la ligne fonctionnera bien.
andreialecu
152
@rball, nonsense:jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1'));
eyelidlessness
39
pst était correct, il est possible de le faire de différentes manières sans 'eval'. Crockford dit que «eval Is Evil» parce qu'il est moins lisible et moins sécurisé, en outre, il peut en outre impliquer qu'il est moins efficace et plus dangereux car il frappe le compilateur javascript.
Mark Rogers
13
@Edy: new Functionest presque aussi mauvais que eval: dev.opera.com/articles/view/efficient-javascript/…
Marcel Korpel
5
@Edy: C'est une autre forme d'évaluation, et c'est tout aussi «mal». Analyser la chaîne à la place (voir ma réponse ci-dessous)
Roy Tinker
98

Pour ceux qui utilisent Newtonsoft Json.NET , découvrez comment le faire via Native JSON dans IE8, Firefox 3.5 plus Json.NET .

La documentation sur la modification du format des dates écrite par Json.NET est également utile: Sérialisation des dates avec Json.NET

Pour ceux qui sont trop paresseux, voici les étapes rapides. Comme JSON a une implémentation DateTime lâche, vous devez utiliser le IsoDateTimeConverter(). Notez que depuis Json.NET 4.5, le format de date par défaut est ISO, donc le code ci-dessous n'est pas nécessaire.

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

Le JSON passera par

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

Enfin, du JavaScript pour convertir la date ISO en date 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;
}

Je l'ai utilisé comme ça

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
Jason Jong
la source
6
Le constructeur de date JavaScript peut analyser la chaîne pour vous:new Date("2009-04-12T20:44:55")
David Hogue
5
Avertissement - Les formats et l'analyse du constructeur Date () ne sont pas standard avant ECMAScript 6. Par exemple, IE 9 traite la date que vous donnez au constructeur comme une heure locale même si elle est dans IS0-8601, ce qui est implicite comme UCT partout ailleurs. Ne comptez pas sur le constructeur de date si vous prenez en charge les anciens navigateurs. codeofmatt.com/2013/06/07/…
DanO
L'envoi d'une date non UTC vous causera tôt ou tard des ennuis.
tymtam
Un peu tard pour la fête ici, mais que ferait-il (+ a [1], + a [2] - 1, + a [3], + a [4], + a [5], + a [6]) ; représenter dans ce contexte?
yanant
@yanant - le +a[1]etc représente les morceaux du tableau de l'expression régulière et le le +jetterait à un nombre, donc +a[1]égal à 2009etc. Voici la répartition du tableau: 0: "2009-04-12T20:44:55" 1: "2009" 2: "04" 3: "12" 4: "20" 5: "44" 6: "55"
Jason Jong
67

L'exemple d'origine:

/Date(1224043200000)/  

ne reflète pas la mise en forme utilisée par WCF lors de l'envoi de dates via WCF REST à l'aide de la sérialisation JSON intégrée. (au moins sur .NET 3.5, SP1)

J'ai trouvé la réponse ici utile, mais une légère modification de l'expression régulière est nécessaire, car il semble que le décalage GMT du fuseau horaire soit ajouté au nombre renvoyé (depuis 1970) dans WCF JSON.

Dans un service WCF, j'ai:

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

ApptVisitLinkInfo est défini simplement:

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

Lorsque "Field2" est renvoyé en tant que Json à partir du service, la valeur est:

/Date(1224043200000-0600)/

Notez le décalage de fuseau horaire inclus dans la valeur.

Le regex modifié:

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

Il est légèrement plus impatient et saisit tout entre les parens, pas seulement le premier numéro. L'heure résultante sinze 1970, plus le décalage de fuseau horaire peuvent tous être introduits dans l'éval pour obtenir un objet date.

La ligne résultante de JavaScript pour le remplacement est:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Aaron
la source
10
c'est faux, la nouvelle date (1224043200000-0600) ne soustraira que 600 de la date, dans ce cas 600 millisecondes, pas 6 heures comme il se doit.
ariel
Je pense que le décalage de fuseau horaire n'est inclus que si vous avez un fuseau horaire sur l'objet DateTime dans .NET (qui est le comportement par défaut). Si votre date est en UTC, utilisez DateTime.SpecifyKind (date, DateTimeKind.UTC) et vous obtiendrez la valeur UTC appropriée lors de la sérialisation, sans décalage, que vous pourrez ensuite reconvertir au fuseau horaire de l'utilisateur selon vos besoins. S'il est en heure locale, utilisez .ToUniversalTime () et il se convertira en UTC, et le "Kind" sera déjà spécifié pour vous.
jvenema
en javascript -0100 sera une chaîne binaire alors faites attention!
verbedr
une fois que vous avez converti la date de WCF en JS, que diriez-vous d'inverser. Vous devez dater sous forme d'entier (en utilisant date.getTime ()) que vous souhaitez passer au même WCF?
NitinSingh
65

Ne vous répétez pas - automatisez la conversion de date en utilisant $.parseJSON()

Les réponses à votre message fournissent une conversion manuelle des dates en dates JavaScript. J'ai étendu $.parseJSON()un peu jQuery , il est donc capable d'analyser automatiquement les dates lorsque vous le lui demandez. Il traite les dates formatées ASP.NET ( /Date(12348721342)/) ainsi que les dates formatées ISO ( 2010-01-01T12.34.56.789Z) qui sont prises en charge par les fonctions natives JSON dans les navigateurs (et les bibliothèques comme json2.js).

En tous cas. Si vous ne voulez pas répéter votre code de conversion de date encore et encore, je vous suggère de lire ce billet de blog et d'obtenir le code qui vous facilitera la vie.

Robert Koritnik
la source
61

Si vous dites en JavaScript,

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

vous verrez que c'est la bonne date, et vous pouvez l'utiliser n'importe où dans le code JavaScript avec n'importe quel framework.

John Boker
la source
3
C'est ce que j'aurais pensé aussi, sauf que cela finit par être: var thedate = / Date (1224043200000) /; au moins pour moi ...
rball
2
Date () et Date (1224043200000) donnent tous deux le même résultat dans Chrome et Firefox. Je ne sais pas si cela fonctionnait dans les anciens navigateurs, mais cette réponse ne fonctionne plus dans les navigateurs actuellement.
James
@James, Oui, il donne la date actuelle du navigateur. :(
vissu
9
Vous devez l'écrire comme "nouvelle date (1224043200000)".
BrainSlugs83
60

Cliquez ici pour voir la démo

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

Résultat - "15/10/2008"

utilisateur2007801
la source
Juste une amélioration pour la méthode ci-dessus. fonction 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); date de retour;} date formatée en ddMMyyyy. A bientôt!
Matias
38

Mise à jour

Nous avons une bibliothèque d'interface utilisateur interne qui doit faire face au format JSON intégré ASP.NET de Microsoft, comme /Date(msecs)/, demandé ici à l'origine, et à la plupart des formats de date de JSON, y compris JSON.NET, comme 2014-06-22T00:00:00.0. De plus, nous devons faire face à l'incapacité de oldIE de faire face à tout sauf à 3 décimales .

Nous détectons d'abord le type de date que nous consommons, analysons-le dans un Dateobjet JavaScript normal , puis formatez-le.

1) Détecter le format de date Microsoft

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

2) Détecter le format de date 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) Analyser le format de date MS:

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

4) Analyser le format de date ISO.

Nous avons au moins un moyen de nous assurer que nous avons affaire à des dates ISO standard ou à des dates ISO modifiées pour toujours avoir trois millisecondes ( voir ci-dessus ), donc le code est différent selon l'environnement.

4a) Analyser le format de date ISO standard, faire face aux problèmes 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) Analyser le format ISO avec une décimale fixe de trois millisecondes - beaucoup plus facile:

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

5) Formatez-le:

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) Attachez tout ensemble:

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

    return formatDate(d);
}

L'ancienne réponse ci-dessous est utile pour lier cette mise en forme de date à l'analyse JSON de jQuery afin d'obtenir des objets Date au lieu de chaînes, ou si vous êtes toujours bloqué dans jQuery <1.5 d'une manière ou d'une autre.

Ancienne réponse

Si vous utilisez la fonction Ajax de jQuery 1.4 avec ASP.NET MVC, vous pouvez transformer toutes les propriétés DateTime en objets Date avec:

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

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

Dans jQuery 1.5, vous pouvez éviter de remplacer la parseJSONméthode globalement en utilisant l'option converters dans l'appel Ajax.

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

Malheureusement, vous devez passer à l'ancienne route eval pour que les dates soient analysées globalement sur place - sinon vous devez les convertir au cas par cas après l'analyse.

Chris Moschini
la source
27

Il n'y a pas de type de date intégré dans JSON . Cela ressemble au nombre de secondes / millisecondes d'une époque. Si vous connaissez l'époque, vous pouvez créer la date en ajoutant la bonne quantité de temps.

johnstok
la source
C'est incorrect, JSON utilise des dates Javascript, avec des informations de fuseau horaire ajoutées - l'époque est la même que l'époque de la classe Date javascript (pour des raisons évidentes).
BrainSlugs83
3
@ BrainSlug83 - cette réponse fournit une référence pour l'affirmation que JSON n'a pas de type de date intégré. Si vous n'êtes pas d'accord, veuillez fournir une référence alternative. (Vous ne pensez pas à un cadre spécifique qui a décidé d'un format de chaîne pour représenter les dates, n'est-ce pas? Cela ne fait pas partie de la norme JSON, en effet, cela ne pourrait pas être parce qu'il serait impossible d'inclure une chaîne qui n'est pas censé être pris comme une date mais qui se trouve avoir un ensemble de caractères qui correspondent au modèle de date.)
nnnnnn
25

J'ai également dû chercher une solution à ce problème et j'ai finalement trouvé moment.js qui est une belle bibliothèque qui peut analyser ce format de date et bien d'autres.

var d = moment(yourdatestring)

Cela m'a sauvé des maux de tête, alors j'ai pensé que je partagerais avec vous. :)
Vous pouvez trouver plus d'informations à ce sujet ici: http://momentjs.com/

Venemo
la source
24

J'ai fini par ajouter les "caractères dans l'expression régulière de Panos pour se débarrasser de ceux générés par le sérialiseur Microsoft lors de l'écriture d'objets dans un script en ligne:

Donc, si vous avez une propriété dans votre code C -behind, c'est quelque chose comme

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

Et dans votre aspx vous avez

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

Vous obtiendriez quelque chose comme

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

Remarquez les guillemets doubles.

Pour obtenir ceci dans un formulaire que eval désérialisera correctement, j'ai utilisé:

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

J'utilise Prototype et pour l'utiliser j'ai ajouté

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

Dans jQuery 1.5, tant que vous avez json2.js à couvrir pour les anciens navigateurs, vous pouvez désérialiser toutes les dates provenant d'Ajax comme suit:

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

J'ai inclus une logique qui suppose que vous envoyez toutes les dates du serveur en UTC (ce que vous devriez); le consommateur obtient alors un Dateobjet JavaScript qui a la valeur de ticks appropriée pour refléter cela. C'est-à-dire que l'appel getUTCHours(), etc. à la date retournera la même valeur que sur le serveur, et l'appel getHours()retournera la valeur dans le fuseau horaire local de l'utilisateur tel que déterminé par son navigateur.

Cela ne prend pas en compte le format WCF avec les décalages de fuseau horaire, bien que ce soit relativement facile à ajouter.

Domenic
la source
Juste comme une note: pour que le code fonctionne, vous devez créer la méthode startsWith du type chaîne
Hugo Zapata
21

Utiliser le sélecteur de date jQuery UI - n'a de sens que si vous incluez déjà jQuery UI:

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

production:

15 octobre 2008

dominic
la source
20

Ne pensez pas trop à cela. Comme nous l'avons fait depuis des décennies, passez un décalage numérique par rapport à l'époque standard de facto du 1er janvier 1970 à minuit GMT / UTC / & c en nombre de secondes (ou millisecondes) depuis cette époque. JavaScript l'aime, Java l'aime, C l'aime et Internet l'aime.

Xepoch
la source
2
Et dommage qu'il y ait plus de 20 époques à choisir. en.wikipedia.org/wiki/Epoch_(reference_date)
Jerther
C'est ce qui est bien avec les normes .
Marc L.
18

Chacune de ces réponses a une chose en commun: elles stockent toutes les dates sous la forme d'une seule valeur (généralement une chaîne).

Une autre option consiste à tirer parti de la structure inhérente de JSON et à représenter une date sous forme de liste de nombres:

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

Bien sûr, vous devez vous assurer que les deux extrémités de la conversation s'accordent sur le format (année, mois, jour), et quels champs sont censés être des dates, ... mais cela a l'avantage d'éviter complètement le problème de la date conversion en chaîne. Ce sont tous des chiffres - pas de chaînes du tout. De plus, l'utilisation de la commande: année, mois, jour permet également un tri correct par date.

Penser juste en dehors de la boîte ici - une date JSON ne doit pas être stockée sous forme de chaîne.

Un autre avantage de le faire de cette façon est que vous pouvez facilement (et efficacement) sélectionner tous les enregistrements pour une année ou un mois donné en tirant parti de la façon dont CouchDB gère les requêtes sur les valeurs de tableau.

Nick Perkins
la source
Il existe un format standard pour les dates dans JSON, qui est le format RFC 3339.
gnasher729
@gnasher, ce serait bien, mais ce n'est pas le cas. Il n'y a aucune référence de RFC 7159 à 3339 ou vice versa. Il n'y a pas de format de date JSON standard de jure . Il ne reste que des normes de facto , chacune ayant ses avantages / inconvénients. C'est ce qui est bien avec les normes.
Marc L.
17

Publication dans un fil génial:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Dan Beam
la source
1
Bonne idée, mais que se passe-t-il si un décalage de fuseau horaire est inclus? Mieux vaut utiliser substr (6) dans ce cas au lieu de slice (6, -2) - voir ma réponse ci-dessous.
Roy Tinker
17

Juste pour ajouter une autre approche ici, «l'approche des tiques» que WCF adopte est sujette à des problèmes avec les fuseaux horaires si vous n'êtes pas extrêmement prudent comme décrit ici et ailleurs. J'utilise donc maintenant le format ISO 8601 que les deux .NET et JavaScript prennent dûment en charge, y compris les décalages de fuseau horaire. Voici les détails:

Dans WCF / .NET:

Où CreationDate est un System.DateTime; ToString ("o") utilise le spécificateur de format aller-retour de .NET qui génère une chaîne de date conforme à ISO 8601

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

En JavaScript

Juste après avoir récupéré le JSON, je corrige les dates pour être des objets Date JavaSript en utilisant le constructeur Date qui accepte une chaîne de date 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());
    }
)

Une fois que vous avez une date JavaScript, vous pouvez utiliser toutes les méthodes de date pratiques et fiables comme toDateString , toLocaleString , etc.

actifscott
la source
16
var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

Existe-t-il une autre option sans utiliser la bibliothèque jQuery?

blgnklc
la source
Il s'agit d'une nouvelle question qui doit être posée comme sa propre question et non pas intégrée ici.
Spencer Sullivan
11

Cela peut également vous aider.

 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
la source
10

Voici une solution assez simple pour analyser les dates JSON. Utilisez les fonctions ci-dessous selon vos besoins. Il vous suffit de passer le format JSON Date récupéré en paramètre aux fonctions ci-dessous:

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
la source
10

Vous pouvez également utiliser la bibliothèque JavaScript moment.js , qui est utile lorsque vous prévoyez de traiter différents formats localisés et d'effectuer d'autres opérations avec des valeurs de dates:

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

Mettre en place la localisation est aussi simple que d'ajouter des fichiers de configuration (vous les obtenez sur momentjs.com) à votre projet et de configurer la langue:

moment.lang('de');
martinoss
la source
9

Je reçois la date comme ceci:

"/Date(1276290000000+0300)/"

Dans certains exemples, la date est dans des formats légèrement différents:

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

etc.

J'ai donc créé le RegExp suivant:

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

et le code final est:

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

J'espère que cela aide.

Mise à jour: j'ai trouvé ce lien de Microsoft: comment sérialiser des dates avec JSON?

Cela ressemble à celui que nous recherchons tous.

Michael Vashchinsky
la source
1
Les remplacements d'expressions régulières sont lents ... Il est beaucoup plus rapide de saisir la partie entière à l'aide de substr (6) et de la passer à parseInt () - voir ma réponse ci-dessous.
Roy Tinker du
Jetez également un œil à la date Javascript en millisecondes et au fuseau horaire
Bergi
9

Vérifiez la norme ISO de date; un peu comme ça:

yyyy.MM.ddThh:mm

Cela devient 2008.11.20T22:18.

Thomas Hansen
la source
Selon JSON Schema, le format "date-heure" correspond à RFC 3339, section 5.6. Vous devez donc écrire "aaaa-MM-jjTHH: mm: ssZ" pour les dates en GMT, ou le Z remplacé par un fuseau horaire comme + hh: mm.
gnasher729
Le problème est que WCF et autres "anciennes" sérialisations MS JSON n'utilisent pas ce format, et cela doit être pris en compte.
Marc L.
9

C'est frustrant. Ma solution a été d'analyser le "/ et /" de la valeur générée par JavaScriptSerializer d'ASP.NET afin que, bien que JSON n'ait pas de littéral de date, il est toujours interprété par le navigateur comme une date, ce qui est tout ce que j'ai vraiment vouloir:{"myDate":Date(123456789)}

Convertisseur JavaScript personnalisé pour DateTime?

Je dois souligner l'exactitude du commentaire de Roy Tinker. Ce n'est pas du JSON légal. C'est un hack sale et sale sur le serveur pour supprimer le problème avant qu'il ne devienne un problème pour JavaScript. Cela va étouffer un analyseur JSON. Je l'ai utilisé pour décoller, mais je ne l'utilise plus. Cependant, je pense toujours que la meilleure réponse réside dans le changement de la façon dont le serveur formate la date, par exemple, ISO, comme mentionné ailleurs.

StarTrekRedneck
la source
2
Ce n'est pas du JSON légal. Cela ne fonctionnera que lors de l'évaluation avec un interpréteur Javascript. Mais si vous utilisez un décodeur JSON, il s'étouffera.
Roy Tinker
1
D'accord. Et si je ne faisais que traiter cette seule donnée, je ne la considérerais pas. Mais si je traite d'un objet de plusieurs dates et d'autres propriétés, il est plus facile d'évaluer le tout que de sélectionner les propriétés une par une. En fin de compte, le problème racine est l'absence de date JSON (légale). Jusqu'à ce que cela existe, nous sommes laissés à nos hacks créatifs.
StarTrekRedneck
8

Un post tardif, mais pour ceux qui ont cherché ce post.

Imagine ça:

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

Comme vous pouvez le voir, j'utilise la fonctionnalité de C # 3.0 pour créer les génériques "Auto". C'est un peu paresseux, mais j'aime ça et ça marche. Juste une note: Profile est une classe personnalisée que j'ai créée pour mon projet d'application web.

Ray Linder
la source
donc à chaque fois que vous ajoutez un nouveau rôle [Autoriser (Rôles = "Ressources Humaines")], vous devez compiler et déployer? wow .... :)
Alex Nolasco
1
S'il s'agit d'un service JSON, la redirection semble incorrecte. Je retournerais un 404 Not Found si la clé d'entrée est si invalide qu'elle ne peut pas être trouvée, (et aussi 404 si elle n'est vraiment pas trouvée). Lorsque mes utilisateurs ne sont pas connectés, je renvoie 403 Interdit.
Richard Corfield
C'est une méthode "réutilisable". Par exemple, si je voulais obtenir des données utilisateur d'une autre vue, je peux les obtenir tant que je fournis l'identifiant. Cependant, si l'ID n'est pas fourni, la page redirige vers une liste d'utilisateurs (Index) pour sélectionner un utilisateur. Une solution simple nécessaire pour l'application, exactement comme mon cerveau l'a préparée à ce moment-là.
Ray Linder,
8

Pour info, pour toute personne utilisant Python côté serveur: datetime.datetime (). Ctime () retourne une chaîne qui est nativement analysable par "new Date ()". Autrement dit, si vous créez une nouvelle instance datetime.datetime (comme avec datetime.datetime.now), la chaîne peut être incluse dans la chaîne JSON, puis cette chaîne peut être transmise en tant que premier argument au constructeur Date. Je n'ai pas encore trouvé d'exceptions, mais je ne l'ai pas testé trop rigoureusement non plus.

Kyle Alan Hale
la source
8

Solution Mootools:

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

Nécessite mootools-more. Testé avec mootools-1.2.3.1-more sur Firefox 3.6.3 et IE 7.0.5730.13

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

Ajoutez le plugin jQuery UI dans votre page:

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

Et si .NET revient ...

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

Et puis en JavaScript ...

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