jquery - يوجد - متى تأسست مايكروسوفت




كيف يمكنني تنسيق تاريخ Microsoft JSON؟ (20)

محدث

لدينا مكتبة داخلية لـ UI يجب أن تتوافق مع تنسيق JSON المدمج في ASP.NET الخاص بـ Microsoft ، مثل /Date(msecs)/ ، سألنا عن الأصل في الأصل ، ومعظم تنسيق JSON بما في ذلك JSON.NET ، مثل 2014-06-22T00:00:00.0 . بالإضافة إلى ذلك نحن بحاجة للتعامل مع عدم القدرة على التعامل مع أي شيء سوى 3 منازل عشرية .

نكتشف أولاً أي نوع من التواريخ التي نستهلكها ، ونحللها إلى كائن Date جافا سكريبت عادي ، ثم نساعدك على ذلك.

1) كشف تنسيق تاريخ مايكروسوفت

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

2) كشف تنسيق تاريخ 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) تنسيق تاريخ تحليل MS:

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

4) تحليل تنسيق التاريخ ISO.

لدينا على الأقل طريقة للتأكد من أننا نتعامل مع تواريخ ISO القياسية أو تعديل مواعيد ISO بحيث يكون لدينا دائمًا ثلاثة أجزاء من الألف من الثانية ( انظر أعلاه ) ، لذلك تختلف الشفرة وفقًا للبيئة.

4 أ) تحليل صيغة ISO القياسية للتاريخ ، والتعامل مع مشكلات 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) تحليل تنسيق ISO مع أماكن عشرية عشرية ثابتة - أسهل بكثير:

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

5) قم بتنسيقه:

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) اربطها معًا:

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

    return formatDate(d);
}

تُعد الإجابة القديمة أدناه مفيدة لربط تنسيق التاريخ هذا بتحليل JSON الخاص بـ jQuery بحيث تحصل على كائنات التاريخ بدلاً من السلاسل ، أو إذا كنت لا تزال عالقة في jQuery <1.5 بطريقة أو بأخرى.

الاجابه القديمة

إذا كنت تستخدم وظيفة Ajax 1.4 jQuery مع ASP.NET MVC ، فيمكنك تشغيل جميع خصائص DateTime في كائنات التاريخ باستخدام:

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

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

في jQuery 1.5 يمكنك تجنب تجاوز طريقة parseJSON عالمياً باستخدام خيار المحولات في استدعاء Ajax.

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

لسوء الحظ ، عليك التبديل إلى مسار eval القديم حتى تتمكن من تحليل التواريخ على مستوى العالم - وإلا فأنت تحتاج إلى تحويلها على أساس ما بعد كل حالة على حدة.

أنا أخذ صدعتي الأولى في Ajax مع jQuery. أتلقى بياناتي على صفحتي ، ولكن أواجه بعض المشكلات في بيانات JSON التي تم إرجاعها لأنواع بيانات التاريخ. في الأساس ، أحصل على سلسلة ظهر تبدو كالتالي:

/Date(1224043200000)/

من شخص جديد كليًا إلى JSON - كيف أقوم بتنسيق ذلك بتنسيق تاريخ قصير؟ هل يجب التعامل مع هذا في مكان ما في رمز jQuery؟ لقد حاولت استخدام المكون الإضافي jQuery.UI.datepicker باستخدام $.datepicker.formatDate() بدون أي نجاح.

لمعلوماتك: إليك الحل الذي توصلت إليه باستخدام مزيج من الإجابات هنا:

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

حصل هذا الحل على الكائن من طريقة رد الاتصال وعرض التواريخ على الصفحة بشكل صحيح باستخدام مكتبة تنسيق التاريخ.


لا تكرر نفسك - قم بتحويل التاريخ تلقائيًا باستخدام $.parseJSON()

توفر الإجابات على رسالتك تحويل التاريخ يدويًا إلى تواريخ جافا سكريبت. لقد قمت بتمديد jQuery's $.parseJSON() فقط قليلاً ، حتى تتمكن من تحليل التواريخ تلقائيًا عندما تقوم $.parseJSON() . يقوم بمعالجة تواريخ ASP.NET المنسقة ( /Date(12348721342)/ ) بالإضافة إلى تواريخ ISO المنسقة ( 2010-01-01T12.34.56.789Z ) التي تدعمها وظائف JSON الأصلية في المستعرضات (والمكتبات مثل json2.js).

على أي حال. إذا كنت لا ترغب في تكرار رمز التحويل الخاص بك مرة بعد مرة ، أقترح عليك قراءة هذه المدونة والحصول على الرمز الذي سيجعل حياتك أسهل قليلاً.


Eval ليست ضرورية. هذا سوف يعمل بشكل جيد:

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

تقوم الدالة substr بإخراج "/ Date (" جزء ، وتحصل الدالة parseInt على العدد الصحيح وتتجاهل ") /" في النهاية. يتم تمرير الرقم الناتج في منشئ التاريخ.

تحرير: لقد تركت عن قصد خارج الجذر (الوسيطة الثانية ل parseInt) ؛ انظر تعليقي أدناه . أيضًا ، أتفق تمامًا مع تعليق Rory : يُفضل استخدام المواعيد ISO-8601 على هذا التنسيق القديم - لذلك لا ينبغي استخدام هذا التنسيق بشكل عام للتطوير الجديد. شاهد مكتبة Json.NET الممتازة للحصول على بديل رائع يقوم بتسلسل التواريخ باستخدام تنسيق ISO-8601.

بالنسبة إلى ISO-8601 تواريخ JSON المهيأة ، ما عليك سوى تمرير السلسلة إلى مُنشئ التاريخ:

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

أحصل على التاريخ مثل هذا:

"/Date(1276290000000+0300)/"

في بعض الأمثلة يكون التاريخ بتنسيقات مختلفة قليلاً:

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

إلخ

لذلك توصلت مع RegExp التالية:

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

والرمز النهائي هو:

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

آمل أن يساعد.

تحديث: لقد عثرت على هذا الرابط من Microsoft: كيف أقوم بتسلسل التواريخ مع JSON؟

هذا يبدو وكأنه واحد ونحن جميعا نبحث عنه.


إذا كنت تقول في JavaScript ،

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

سترى أنه التاريخ الصحيح ، ويمكنك استخدام ذلك في أي مكان في شفرة جافا سكريبت مع أي إطار عمل.


المثال الأصلي:

/Date(1224043200000)/  

لا يعكس التنسيق المستخدم بواسطة WCF عند إرسال التواريخ عبر WCF REST باستخدام التسلسل JSON المضمّن. (على الأقل على. NET 3.5 ، SP1)

لقد وجدت أن الإجابة هنا مفيدة ، ولكن هناك حاجة إلى تعديل طفيف للتعبير المعتاد ، حيث يبدو أن المنطقة الزمنية بتوقيت GMT يتم إلحاقها بالرقم الذي تم إرجاعه (منذ عام 1970) في WCF JSON.

في خدمة WCF لدي:

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

يتم تعريف ApptVisitLinkInfo ببساطة:

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

عندما يتم إرجاع "Field2" كـ Json من الخدمة ، تكون القيمة:

/Date(1224043200000-0600)/

لاحظ إزاحة المنطقة الزمنية كجزء من القيمة.

تعديل regex:

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

إنه أكثر شغفاً قليلاً ويمسك بكل شيء بين الأرفف وليس فقط الرقم الأول. يمكن تغذية الوقت الناتج sinise 1970 ، بالإضافة إلى إزاحة المنطقة الزمنية في eval للحصول على كائن تاريخ.

السطر الناتج من JavaScript للاستبدال هو:

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

انتهى بي الأمر بإضافة "الأحرف إلى تعبير Panos العادي للتخلص من تلك التي تم إنشاؤها بواسطة مسلسل Microsoft عند كتابة الكائنات في نص برمجي داخلي:

لذا إذا كان لديك خاصية في C # code-behind فهذا شيء مثل

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

وفي ASX لديك

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

ستحصل على شيء من هذا القبيل

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

لاحظ علامات الاقتباس المزدوجة.

للحصول على هذا النموذج الذي سيتم إلغاء عملية eval بشكل صحيح ، استخدمت:

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

يمكنني استخدام Prototype واستخدامه أضفت

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

باستخدام jQuery UI datepicker - من المنطقي حقًا فقط إذا كنت بالفعل متضمنة jQuery UI:

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

انتاج:

15 أكتوبر 2008


حل Mootools:

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

يتطلب mootools أكثر. تم اختباره باستخدام mootools-1.2.3.1-more على Firefox 3.6.3 و IE 7.0.5730.13


رسالة متأخرة ، ولكن بالنسبة لأولئك الذين بحثوا في هذا المنشور.

تخيل هذا:

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

كما ترى ، أستخدم ميزة C # 3.0 لإنشاء Generics "تلقائي". انها كسول بعض الشيء ، ولكن أنا أحب ذلك ويعمل. مجرد ملاحظة: الملف الشخصي هو فئة مخصصة قمت بإنشائها لمشروع تطبيقات الويب الخاص بي.


في jQuery 1.5 ، طالما لديك json2.js لتغطية المتصفحات القديمة ، يمكنك إلغاء تسلسل جميع التواريخ القادمة من Ajax على النحو التالي:

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

أدرجت المنطق الذي يفترض أنك ترسل كل التواريخ من الخادم باسم UTC (الذي يجب عليك) ؛ المستهلك ثم يحصل على كائن Date JavaScript يحتوي على قيمة علامات التجزئة المناسبة لعكس هذا. وهذا يعني أن استدعاء getUTCHours() ، وما إلى ذلك في التاريخ سيعود بنفس القيمة كما كان على الخادم ، getHours() استدعاء getHours() إلى إرجاع القيمة في المنطقة الزمنية المحلية للمستخدم وفقًا لما يحدده المتصفح.

لا يأخذ هذا في الاعتبار صيغة WCF مع إزاحة المنطقة الزمنية ، على الرغم من سهولة إضافتها نسبيًا.


في ما يلي حل بسيط جدًا لتحليل تواريخ JSON. استخدم الوظائف التالية حسب متطلباتك. تحتاج فقط إلى تمرير تنسيق JSON تم جلب التاريخ كمعلمة للوظائف أدناه:

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

لأولئك الذين يستخدمون Newtonsoft Json.NET ، اقرأ عن كيفية القيام بذلك عبر Native JSON في IE8 ، Firefox 3.5 plus Json.NET .

كما أن الوثائق المتعلقة بتغيير تنسيق التواريخ التي كتبها Json.NET مفيدة: Serializing Dates with Json.NET

بالنسبة إلى الكسالى جدًا ، إليك الخطوات السريعة. نظرًا لأن JSON يحتوي على تطبيق DateTime فضفاض ، فأنت بحاجة إلى استخدام IsoDateTimeConverter() . لاحظ أنه اعتبارًا من Json.NET 4.5 ، يكون تنسيق التاريخ الافتراضي هو ISO ، لذلك لا يلزم وجود الشفرة أدناه.

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

سوف تأتي JSON من خلال

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

أخيرًا ، بعض جافا سكريبت لتحويل تاريخ ISO إلى تاريخ جافا سكريبت:

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

اعتدت عليه مثل هذا

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);

لا تفكر في هذا. مثلما فعلنا منذ عقود ، نجحنا في إزاحة رقمية من العصر القياسي الواقعي في 1 يناير 1970 منتصف الليل بتوقيت جرينتش / UTC / & c في عدد الثواني (أو ميلي ثانية) منذ هذه الحقبة. جافا سكريبت يحبها ، جافا يحبها ، C يحبها ، ويحبها الإنترنت.


لمعلوماتك ، لأي شخص يستخدم Python على جانب الخادم: datetime.datetime (). ctime () بإرجاع سلسلة يتم توزيعها من قبل "new Date ()". بمعنى ، إذا قمت بإنشاء مثيل datetime.datetime جديد (مثل datetime.datetime.now) ، يمكن تضمين السلسلة في سلسلة JSON ، ومن ثم يمكن تمرير هذه السلسلة كوسيطة أولى إلى مُنشئ التاريخ. لم أجد حتى الآن أي استثناءات ، لكني لم أختبرها بدقة.


ماذا لو .NET ...

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

ثم في JavaScript ...

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

واضطررت أيضاً إلى البحث عن حل لهذه المشكلة ، وفي نهاية المطاف ، صادفت moment.js وهي مكتبة جميلة يمكنها تحليل تنسيق التاريخ وغير ذلك الكثير.

var d = moment(yourdatestring)

أنقذت بعض الصداع بالنسبة لي لذا ظننت أنني سأشاركها معك. :)
يمكنك العثور على مزيد من المعلومات حول هذا الموضوع هنا: http://momentjs.com/


يمكنك أيضًا استخدام مكتبة جافا سكريبت http://momentjs.com/ ، والتي تأتي في متناول اليد عندما تخطط للتعامل مع تنسيقات مترجمة مختلفة وإجراء عمليات أخرى مع قيم التواريخ:

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

يعد إعداد الترجمة أمرًا سهلاً مثل إضافة ملفات التهيئة (تحصل عليها في اللحظة) إلى مشروعك وتهيئة اللغة:

moment.lang('de');

هذا يمكن أن يساعدك أيضًا.

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

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

هل هناك خيار آخر بدون استخدام مكتبة jQuery؟





json