Question

Je fais mes premiers pas chez Ajax avec jQuery. Mes données sont stockées sur ma page, mais je rencontre des problèmes avec les données JSON renvoyées pour les types de données Date. En gros, je reçois une chaîne qui ressemble à ceci:

/Date(1224043200000)/

D'une personne totalement nouvelle en JSON - Comment puis-je formater ceci en un format de date court? Est-ce que cela devrait être géré quelque part dans le code jQuery? J'ai essayé le jQuery.UI.datepicker plugin en utilisant $.datepicker.formatDate() sans aucun succès.

FYI: Voici la solution que j'ai trouvée en combinant les 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 a correctement affiché les dates sur la page à l'aide de la bibliothèque de formats de date.

Était-ce utile?

La solution

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

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

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

J'ai volontairement laissé de côté la base (le deuxième argument de parseInt); voir mon commentaire ci-dessous .

De plus, je suis tout à fait d'accord avec le commentaire de Rory : Les dates ISO-8601 sont préférables à cet ancien format - ce format ne devrait donc généralement pas être utilisé pour de nouveaux développements. Consultez l'excellente bibliothèque Json.NET pour une excellente solution de rechange qui sérialise les dates au format ISO-8601.

Pour les dates JSON au format ISO-8601, il suffit de transmettre la chaîne au constructeur <=>:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support

Autres conseils

Vous pouvez utiliser ceci pour obtenir une date de JSON:

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

Vous pouvez ensuite utiliser le script un format de date JavaScript (1,2 Ko lorsque minified et gzipped) pour l'afficher à votre guise.

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

La documentation sur la modification du format des dates écrites par Json.NET est également utile: Dates de sérialisation avec Json.NET

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

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

Le code JSON apparaîtra sous la forme

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

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

L'exemple d'origine:

/Date(1224043200000)/  

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

J'ai trouvé la réponse utile, mais une légère modification de l'expression rationnelle est requise, car il semble que l'offset GMT du fuseau horaire est ajouté au nombre renvoyé (depuis 1970) dans JSON WCF.

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

When " Field2 " est renvoyé en tant que Json du service dont la valeur est:

/Date(1224043200000-0600)/

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

La regex modifiée:

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

Il est légèrement plus impatient et saisit tout entre les parens, pas seulement le premier chiffre. Le temps résultant 1970, plus le décalage horaire, peuvent tous être introduits dans l’évaluation pour obtenir un objet de date.

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

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");

Ne vous répétez pas - automatisez la conversion de date à l'aide de $.parseJSON()

Les réponses à votre message fournissent une conversion manuelle des dates en dates JavaScript. JQuery n’a que légèrement étendu /Date(12348721342)/ sur jQuery afin qu’il puisse automatiquement analyser les dates lorsque vous le lui demandez. Il traite les dates au format ASP.NET (2010-01-01T12.34.56.789Z) ainsi que les dates au format ISO (<=>) prises en charge par les fonctions JSON natives des navigateurs (et des bibliothèques comme json2.js).

Quoi qu'il en soit. Si vous ne voulez pas répéter votre code de conversion de date encore et encore, je vous suggère de lire cet article de blog et obtenez le code qui vous facilitera la vie.

Si vous dites en JavaScript,

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

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

Cliquez ici pour consulter 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 &";

Mis à jour

Nous avons une bibliothèque d'interface utilisateur interne qui doit gérer à la fois le format JSON intégré de Microsoft ASP.NET, tel que /Date(msecs)/, à l'origine, et la plupart des formats de date JSON, y compris JSON.NET, tels que 2014-06-22T00:00:00.0. En outre, nous devons faire face à l'incapacité de oldIE à faire face à autre chose qu'à trois décimales .

Nous détectons d’abord le type de date que nous consommons, nous l’analysons dans un objet JavaScript Date normal, puis nous le formaterons.

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 traitons avec des dates ISO standard ou des dates ISO modifiées pour toujours avoir trois millisecondes ( voir ci-dessus ), le code est donc 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) Nouez le tout:

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 ce format 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 en quelque sorte.

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 redéfinir la méthode parseJSON globalement en utilisant l'option de conversion dans l'appel Ajax.

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

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

Je devais aussi chercher une solution à ce problème et finalement je suis tombé sur moment.js, une jolie bibliothèque capable d’analyser ce format de date et bien d’autres.

var d = moment(yourdatestring)

Cela m'a évité des maux de tête, alors j'ai pensé le partager avec vous. :)
Vous trouverez des informations supplémentaires à ce sujet ici: http://momentjs.com/

Il n'existe pas de type de date intégré dans JSON . Cela ressemble au nombre de secondes / millisecondes de certaines époques. Si vous connaissez l’époque, vous pouvez créer la date en ajoutant la durée appropriée.

J'ai fini par ajouter les caractères " dans l'expression régulière de Panos afin de supprimer 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 C # code-behind , cela ressemble à

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

Et dans votre aspx, vous avez

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

Vous obtiendrez quelque chose comme

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

Notez les guillemets doubles.

Pour obtenir cela dans un formulaire dont eval va correctement désérialiser, j'ai utilisé:

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

J'utilise Prototype et je l'ai utilisé

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

Ne pensez pas trop à ça. Comme nous le faisons depuis des décennies, transmettez un décalage numérique par rapport à l’époque standard de facto du 1er janvier 1970 à minuit GMT / UTC / & Et exprimez-le en secondes (ou millisecondes) depuis cette époque. JavaScript l'aime, Java l'aime, C l'aime et Internet l'aime.

Utilisation du datepicker de l'interface utilisateur jQuery: cela n'a de sens que si vous incluez déjà l'interface utilisateur jQuery:

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

sortie:

  

15 octobre 2008

Chacune de ces réponses a une chose en commun: elles stockent toutes les dates sous forme de valeur unique (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 devrez vous assurer que les deux bouts de la conversation s’accordent sur le format (année, mois, jour) et sur les champs destinés à être des dates, mais cela présente l’avantage d’éviter complètement problème de conversion de date en chaîne. Ce sont tous des chiffres - pas de ficelle du tout. De plus, l'utilisation de l'ordre: année, mois et jour permet également un tri correct par date.

Il suffit de sortir des sentiers battus: une date JSON ne doit pas nécessairement être stockée sous forme de chaîne.

Un autre avantage de procéder de cette manière est que vous pouvez facilement (et efficacement) sélectionner tous les enregistrements pour une année ou un mois donné en exploitant la méthode CouchDB traite les requêtes sur les valeurs d'un tableau.

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));
var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

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

Juste pour ajouter une autre approche ici, la & "ticks approche" & "; ce que WCF est sujet aux problèmes de fuseaux horaires si vous ne faites pas très attention, comme décrit ici et ailleurs . Donc, j'utilise maintenant le format ISO 8601 que les deux .NET & Amp; JavaScript dûment pris en charge qui inclut les décalages de fuseau horaire. Voici les détails:

Dans WCF / .NET:

Où CreationDate est un System.DateTime; ToString (& "; <;>") Utilise le .NET Spécificateur de format aller-retour générant 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 qu'elles soient des objets Date JavaSript à l'aide du 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 Date pratiques et fiables telles que toDateString , toLocaleString , etc.

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 ça aide.

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

Cela semble être celui que nous recherchons tous.

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

Ci-dessous, 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 tant que 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;
}

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

Vérifiez la date ISO standard; un peu comme ceci:

yyyy.MM.ddThh:mm

Cela devient 2008.11.20T22:18.

C'est frustrant. Ma solution a été d'analyser les & Quot; / et / & Quot; à partir de la valeur générée par JavaScriptSerializer d'ASP.NET, de sorte que, même si JSON n'a pas de date littérale, il est toujours interprété par le navigateur comme une date, ce que tout ce que je veux vraiment: {"myDate":Date(123456789)}

JavaScriptConverter personnalisé pour DateTime?

Je dois souligner la précision du commentaire de Roy Tinker. Ce n'est pas légal JSON. Il est difficile de supprimer le problème avant que cela ne devienne un problème pour JavaScript. Cela étouffera un analyseur JSON. Je l'ai utilisé pour décoller, mais je ne l'utilise plus. Cependant, je pense toujours que la meilleure solution consiste à changer la façon dont le serveur formate la date, par exemple, ISO, comme mentionné ailleurs.

Ajoutez le plug-in de l'interface utilisateur jQuery dans votre page:

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

Vous pouvez également utiliser la bibliothèque JavaScript moment.js , ce qui est pratique lorsque vous envisagez de traiter avec différents environnements localisés. formate et effectue 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;
}

La configuration de la localisation est aussi simple que l’ajout de fichiers de configuration (vous les obtenez sur momentjs.com) à votre projet et la configuration de la langue:

moment.lang('de');

Message tardif, mais pour ceux qui ont cherché ce message.

Imaginez ceci:

    [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 constater, j'utilise la fonctionnalité C # 3.0 pour créer le & "Auto &"; Génériques. C'est un peu paresseux, mais j'aime ça et ça marche. Juste une remarque: Profile est une classe personnalisée que j'ai créée pour mon projet d'application Web.

Solution Mootools:

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

Nécessite mootools-more. Testé à l'aide de mootools-1.2.3.1-more sur Firefox 3.6.3 et IE 7.0.5730.13

Pour votre information, si vous utilisez Python côté serveur: datetime.datetime (). ctime () renvoie une chaîne qui est nativement analysable par & "new Date () &" ;. Autrement dit, si vous créez une nouvelle instance datetime.datetime (telle que 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'exception, mais je ne l'ai pas non plus testé de manière rigoureuse.

Et si .NET renvoie ...

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

Et ensuite en JavaScript ...

var x = new Date("2013-09-17 15:18:53Z");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top