Как мне отформатировать дату Microsoft JSON? - PullRequest
1907 голосов
/ 16 октября 2008

Я беру свою первую трещину в Ajax с помощью jQuery. Я перенесу свои данные на свою страницу, но у меня возникли некоторые проблемы с данными JSON, которые возвращаются для типов данных Date. По сути, я получаю строку, которая выглядит следующим образом:

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

Это решение получило мой объект из метода обратного вызова и правильно отобразило даты на странице, используя библиотеку формата даты.

Ответы [ 40 ]

1639 голосов
/ 23 февраля 2010

eval() не обязательно. Это будет хорошо работать:

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

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


Я намеренно пропустил основание (2-й аргумент parseInt); см мой комментарий ниже .

Кроме того, я полностью согласен с комментарием Рори : даты ISO-8601 предпочтительнее этого старого формата - поэтому этот формат обычно не следует использовать для новой разработки См. Превосходную библиотеку Json.NET для прекрасной альтернативы, которая сериализует даты, используя формат ISO-8601.

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

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
124 голосов
/ 16 октября 2008

Вы можете использовать это, чтобы получить дату из JSON:

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

И затем вы можете использовать скрипт JavaScript Date Format (1,2 КБ при минимизации и сжатии), чтобы отобразить его так, как вы хотите.

93 голосов
/ 19 января 2010

Для тех, кто использует 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);
63 голосов
/ 30 декабря 2009

Исходный пример:

/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)");
60 голосов
/ 27 декабря 2010

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

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

Во всяком случае. Если вы не хотите повторять ваш код преобразования даты снова и снова, я предлагаю вам прочитать этот пост и получить код, который облегчит вашу жизнь.

59 голосов
/ 16 октября 2008

Если вы говорите в JavaScript,

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

вы увидите, что это правильная дата, и вы можете использовать ее в любом месте кода JavaScript с любым фреймворком.

55 голосов
/ 17 марта 2013

Нажмите здесь, чтобы проверить Демо

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"

36 голосов
/ 08 февраля 2011

Обновлено

У нас есть внутренняя библиотека пользовательского интерфейса, которая должна справляться как со встроенным форматом JSON Microsoft ASP.NET, например /Date(msecs)/, о котором мы спрашивали изначально, так и с большинством форматов дат JSON, включая JSON.NET, например 2014-06-22T00:00:00.0. Кроме того, нам нужно справиться с неспособностью oldIE справиться с чем-либо, кроме 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) Parse 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, чтобы вы получали объекты Date вместо строк или если вы все равно застряли в jQuery <1.5. </p>

Старый ответ

Если вы используете функцию 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, чтобы Dates мог анализироваться глобально, в противном случае вам нужно конвертировать их в более индивидуальном порядке после разбора.

24 голосов
/ 15 мая 2013

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

var d = moment(yourdatestring)

Это избавило меня от головной боли, поэтому я решил поделиться с вами. :)
Вы можете найти больше информации об этом здесь: http://momentjs.com/

23 голосов
/ 09 октября 2009

В итоге я добавил символы "в регулярное выражение Panos, чтобы избавиться от символов, сгенерированных сериализатором Microsoft для записи объектов во встроенный скрипт:

Так что если у вас есть свойство в вашем коде C # , это что-то вроде

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

И в вашем aspx у вас есть

<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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...