Питання Як мені відформатувати дату Microsoft JSON?


Я беру свою першу тріщину Ajax з jQuery. Я отримую свої дані на свою сторінку, але у мене виникають проблеми з даними JSON, які повертаються для типів даних дат. У принципі, я отримую рядок назад, що виглядає так:

/Date(1224043200000)/

Від кого-то абсолютно нового до JSON - Як мені відформатувати його в короткий формат дати? Чи повинен цей код оброблятися десь у коді jQuery? Я пробував jQuery.UI.datepicker плагін використовуючи $.datepicker.formatDate() без будь-якого успіху.

FYI: Ось рішення, яке я запропонував, використовуючи комбінацію відповідей тут:

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

Це рішення отримало мій об'єкт від методу зворотного виклику і відображало дати на сторінці правильно, використовуючи бібліотеку формату дати.


1793


походження


Це може бути цікаво: hanselman.com/blog/... - citronas
Формат /Date(...)/ / формат специфічний для вбудованого формату JSON Date Microsoft - він не є частиною будь-якого стандарту, а JSON, що надходить з Javascript, має стандартний: формат ISO Javascript визначає: stackoverflow.com/a/15952652/176877  Отже, це питання стосується формату дати JSON у форматі Microsoft. Я змінив назву, щоб прояснити це. - Chris Moschini
Ти жартуєш! Корпорація Майкрософт створила свій власний обмін на JSON! і на датах !! Коли вони навчаться! - Nick.McDermaid
Використовуйте Newtonsoft JSON на .NET стороні, щоб мати чудові набрані значення на стороні JS, просто скористайтеся: github.com/RickStrahl/json.date-extensions - baHI


Відповіді:


Eval не є необхідним. Це буде добре працювати:

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

Функція substr виводить частину "/ Date ("), а функція parseInt отримує ціле число і ігнорує ") /" в кінці. Отримане число передається у конструктор дати.

РЕДАГУВАННЯ: я навмисно виключив radix (другий аргумент для parseInt); побачити мій коментар нижче. Також я повністю згоден з Коментар Рори: Дати ISO-8601 мають перевагу над цим старим форматом - таким чином, цей формат, як правило, не повинен використовуватися для нових розробок. Дивіться відмінно Json.NET бібліотека для чудової альтернативи, яка серіалізує дати за допомогою формату ISO-8601.

Для дат JSON, відформатованих ISO-8601, просто передайте рядок у конструктор дат:

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

1566



@Broam: обидва способи (функція заміни і ця відповідь) повинні змінитися, якщо MS змінить формат. - Roy Tinker
@LeeWhitney: Так, але він буде ігнорувати суфікс (який зсув часовий пояс). Функція parseInt виводить цифри з передньої частини рядка, переданого до нього, доки вона не зустрічається з нечисловим символом або кінцем рядка, в якому вона зупиняється і повертає числовий результат. - Roy Tinker
Не могли б ви оновити його за допомогою radix var date = нова дата (parseInt (jsonDate.substr (6), 10)); - James Kyburz
@JamesKyburz: Кожне правило має винятки, і я думаю, що це, коли застосовується виключення. Дати JSON дати з. NET ніколи мати провідну "0", тому ми можемо безпечно залишити радіс. - Roy Tinker
Варто зазначити, що цей формат дат досить поганий, і загальний хід полягає в форматі дати ISO-8601 в JSON. Побачити hanselman.com/blog/... - Rory


Ви можете використовувати це, щоб отримати дату з JSON:

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

І тоді ви можете використовувати Формат дати JavaScript скрипт (1,2 КБ при мінімізації та стиснення), щоб показати його так, як ви хочете.


115



З лінією немає нічого поганого, послідовність - \ //. Перша коса риска втечу, тому вона не вважається коментарем. Це твій редактор здогадує вас, лінія буде працювати нормально. - andreialecu
@ rball, дурниця: jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1')); - eyelidlessness
ПСТ був правильним, це можна зробити різними способами без "eval". Крокфорд стверджує, що "eval Is Evil", оскільки він менш читабельний і менш надійний, і, крім того, він може означати, що він менш ефективний і більш небезпечний, оскільки він потрапляє на компілятор JavaScript. - Mark Rogers
@ Еді: new Function майже так само погано, як eval: dev.opera.com/articles/view/efficient-javascript/... - Marcel Korpel
@ Еді: Це ще одна форма eval, і це просто як "зло". Проаналізуйте рядок замість (див. Мою відповідь нижче). - Roy Tinker


Для тих, хто використовує Newtonsoft Json.NET, читайте про те, як це зробити через Рідний JSON в IE8, Firefox 3.5 і Json.NET.

Також є корисною документація щодо зміни формату дат, написаної Json.NET: Дати серіалізації з Json.NET

Для тих, хто ледарює, ось швидкі кроки. Оскільки JSON має повну реалізацію DateTime, вам слід скористатись IsoDateTimeConverter(). Зверніть увагу, що оскільки Json.NET 4.5 формат дати за замовчуванням є ISO, то код нижче не потрібний.

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

JSON пройде через

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

Нарешті, JavaScript, щоб перетворити дату ISO в дату 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;
}

Я використовував це як це

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

84



Конструктор дат JavaScript може проаналізувати рядок для вас: new Date("2009-04-12T20:44:55") - David Hogue
Попередження. Конструктор дати () Конфігурація та синтаксичний аналіз не є стандартними перед ECMAScript 6. Наприклад, IE 9 трактує дату, яку ви надаєте конструктору як місцевому часу, навіть якщо вона знаходиться в IS0-8601, яка має на увазі UCT скрізь. Не користуйтеся конструктором дат, якщо ви підтримуєте старі браузери. codeofmatt.com/2013/06/07/... - DanO
Відправка дати, що не належить до UTC, рано чи пізно приведе вас до проблем. - tymtam


Початковий приклад:

/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)/

Зверніть увагу, що зсув часового поясу включений як частина значення.

Змінений регулярний вираз:

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

Це трохи більше бажання і захоплює все між паренесами, а не тільки першим номером. Отриманий час sinze 1970, плюс зміщення часового поясу, може бути поданий у eval, щоб отримати об'єкт дати.

Отримана лінія JavaScript для заміни:

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

57



це неправильно, нова дата (1224043200000-0600) лише відніме 600 від дати, в цьому випадку 600 мілісекунд, а не 6 годин, як це потрібно. - ariel
@ Аріель: Подивіться на це Javascript дата з мілісекундами і часовий пояс - Bergi
Я думаю, що зсув часового поясу включається тільки в тому випадку, якщо у вас є часовий пояс об'єкта DateTime у .NET (який є поведінкою за умовчанням). Якщо ваша дата в UTC, використовуйте DateTime.SpecifyKind (дата, DateTimeKind.UTC), і ви отримаєте правильне значення UTC, коли він серіалізується, без будь-якого зміщення, який потім можна конвертувати назад у часовий пояс користувача, за потреби. Якщо це за місцевим часом, використовуйте .ToUniversalTime (), і він буде конвертувати в UTC, і для нього вже вказано "Добрий". - jvenema
в javascript -0100 буде двійковий рядок, тому будьте обережні! - verbedr
як тільки ви отримаєте дату, конвертовану з WCF в JS, як щодо зворотного. Ви повинні дати ціле число (використовуючи date.getTime ()), який ви хочете перейти до того самого WCF? - NitinSingh


Не повторюй себе - автоматизувати перетворення дат, використовуючи $.parseJSON()

Відповіді на ваш пост забезпечують ручну конвертацію дати до дат JavaScript. Я розширив jQuery $.parseJSON() трохи, так що він може автоматично розбирати дати, коли ви доручаєте це. Він обробляє дати формату ASP.NET (/Date(12348721342)/), а також форматовані датами ISO (2010-01-01T12.34.56.789Z), які підтримуються нативними функціями JSON у браузерах (та бібліотеках, як json2.js).

У всякому разі. Якщо ви не хочете повторювати код конвертування дат знову і знову, я пропоную вам прочитати це повідомлення в блозі і отримаєте код, який зробить ваше життя трохи легше.


53





Якщо ви говорите в JavaScript,

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

ви побачите, що це правильна дата, і ви можете використовувати її в будь-якому місці коду JavaScript за допомогою будь-якої структури.


50



Це те, що я б теж подумав, за винятком того, що він закінчується: var thedate = / Date (1224043200000) /; принаймні для мене ... - rball
Дата () та Дата (1224043200000) обидва дають той самий результат у Chrome і Firefox. Не впевнений, що це працює в старих браузерах, але ця відповідь не працює в браузерах зараз. - James
@ Джеймс, так дає браузер поточну дату. :( - vissu
Вам потрібно записати його як "нову дату (1224043200000)". - BrainSlugs83


Натисніть тут, щоб перевірити Демо

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

Результат - "15.10.2008"


47



Просто поліпшення для вищезазначеного методу. функція formatearFecha (fec) {var value = new Дата (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 of return; ddMMyyyy. Ласкаво просимо! - Matias
Ох !!! Дуже дякую!!! це дійсно зробило мій місяць. - Raihan Ridoy


Оновлено

У нас є внутрішня бібліотека користувальницького інтерфейсу, яка має справлятися з інтегрованим форматом JSON в Microsoft ASP.NET, як-от /Date(msecs)/, запитали про це спочатку, і більшість форматів дати JSON, включаючи JSON.NET, наприклад 2014-06-22T00:00:00.0. Крім того, нам треба справлятися стара нездатність справитися з чим-небудь, окрім 3 десяткових знаків.

Спочатку ми визначаємо, яку дату ми потребуємо, проаналізуємо його на звичайний JavaScript Date об'єкт, потім відформатуйте його.

1) Визначити формат дати Microsoft

// 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, змінені для того, щоб завжди мати три мілісекунди місця (Дивись вище), тому код залежить від оточення.

4a) Розробити стандартний формат дати 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 для jQuery 1.4 із ASP.NET MVC, ви можете перетворити всі властивості DateTime в об'єкти Date за допомогою:

// 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 маршрут, щоб дати Дати, щоб розібратися глобально на місці - в іншому випадку вам потрібно перетворити їх на більш конкретному випадку після коду.


31





Мені також довелося шукати рішення цієї проблеми, і врешті-решт я натрапив на moment.js - це хороша бібліотека, яка може проаналізувати цей формат дати та багато іншого.

var d = moment(yourdatestring)

Це врятувало мені якийсь головний біль, тому я думав, що поділюся з вами. :)
Тут Ви можете знайти додаткову інформацію про це: http://momentjs.com/


21





Я до кінця додав "символи в регулярний вираз Panos, щоб позбутися від тих, які створили serializer Microsoft для написання об'єктів у вбудований скрипт:

Отже, якщо у вас є власність у вашому C # код-позаду це щось на кшталт

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

І у вашому аспик у вас є

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

Ви отримаєте щось подібне

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

Зверніть увагу на подвійні лапки.

Щоб отримати це у формі, яку eval буде правильно десеріалізувати, я використав:

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

я використовую Прототип і використовувати його я додав

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

21





Вбудований тип дат немає JSON. Це виглядає як кількість секунд / мілісекунди з певної епохи. Якщо ви знаєте епоху, ви можете створити дату, додавши в потрібний час.


20



Це неправильно, JSON використовує дату Javascript, додаючи інформацію про часовий пояс - епоха така ж, як і епоха класу дат JavaScript (з очевидних причин). - BrainSlugs83
@ BrainSlug83 - ця відповідь надає посилання на те, що JSON не має вбудованого типу дат. Якщо ви не погоджуєтеся, надайте альтернативну посилання. (Ви не думаєте про конкретну структуру, яка вирішила використовувати формат рядка для позначення дат? Це не є частиною стандарту JSON, воно не могло бути, тому що це не могло б включати в себе рядок, який не є мабуть, вважатиметься датою, але це, мабуть, мати набір символів, що відповідають шаблону дати.) - nnnnnn