Как отформатировать дату 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;
}

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

30 ответов


Eval не требуется. Это будет работать нормально:

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

функция substr извлекает часть" /Date ( ", а функция parseInt получает целое число и игнорирует") / " в конце. Результирующее число передается в конструктор Date.

EDIT: я намеренно опустил radix (второй аргумент для синтаксического анализа); см. мой комментарий ниже. Кроме того, я полностью согласен с Рори!--8-->: даты ИСО-8601 предпочтены над этим старый формат -- поэтому этот формат обычно не следует использовать для новой разработки. См. превосходный Json.NET библиотека для отличной альтернативы, которая сериализует даты с использованием формата ISO-8601.

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

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

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

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

и тогда вы можете использовать формат даты JavaScript script (1.2 KB при уменьшении и gzipped), чтобы отобразить его, как вы хотите.


для тех, кто использует Newtonsoft Json.NET, Читайте о том, как это сделать через родной JSON в IE8, Firefox 3.5 plus 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);

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

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

не повторяйтесь-автоматизация преобразования даты с помощью $.parseJSON()

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

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


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

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

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


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

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

результат - "10/15/2008"


Обновлено

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

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


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

var d = moment(yourdatestring)
Вы можете найти дополнительную информацию об этом здесь:http://momentjs.com/

Я закончил тем, что добавил " символы в регулярное выражение 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()');

я использую прототип и использовать его я добавил

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

нет встроенного типа даты в JSON. Это похоже на количество секунд / миллисекунд от какой-то эпохи. Если вы знаете эпоху, вы можете создать дату, добавив нужное количество времени.


в 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 (что вы должны); потребитель получает JavaScript Date объект, который имеет нужное значение тиков, чтобы отразить это. То есть зовет getUTCHours(), etc. на дату будет возвращено то же значение, что и на сервере, и вызов getHours() возвращает значение в локальном часовом поясе пользователя, как определено их браузером.

это не учитывает WCF формат с смещениями часового пояса, хотя это было бы относительно легко добавить.


Не переусердствуйте. Как мы делали десятилетиями, передайте числовое смещение от де-факто стандартной эпохи 1 января 1970 года midnight GMT/UTC / &c в количестве секунд (или миллисекунд) с этой эпохи. JavaScript это нравится, Java это нравится, C это нравится, и интернет это нравится.


использование jQuery UI datepicker-действительно имеет смысл, только если вы уже включаете jQuery UI:

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

выход:

15 октября 2008


каждый из этих ответов имеет одну общую черту: все они хранят даты как одно значение (обычно строку).

другой вариант-воспользоваться преимуществами внутренней структуры JSON и представить дату в виде списка чисел:

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

конечно, вам нужно будет убедиться, что оба конца разговора согласуют формат (год, месяц, день) и какие поля должны быть датами... но она имеет преимущество полностью избежать вопроса преобразование даты в строку. Все дело в числах - никаких строк. Кроме того, использование заказа: год, месяц, день также позволяет правильно сортировать по дате.

просто думая вне коробки здесь - дата JSON не должна храниться как строка.

еще один бонус к тому, чтобы сделать это таким образом, что вы можете легко (и эффективно) выбрать все записи за данный год или месяц, используя путь CouchDB обрабатывает запросы к значениям массива.


публикация в удивительной теме:

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

есть другой вариант без использования библиотеки jQuery?


просто чтобы добавить еще один подход здесь, "подход тиков", который WCF принимает склонен к проблемам с часовыми поясами, если вы не очень осторожны, такие как описано здесь и в других местах. Поэтому я теперь использую формат ISO 8601, который должным образом поддерживают .NET и JavaScript, который включает смещения часового пояса. Ниже приведены подробности:

в WCF / .NET:

где CreationDate-это система.DateTime; ToString ("o") использует .Сети спецификатор формата туда и обратно который генерирует строку даты, совместимую с ISO 8601

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

В JavaScript

сразу после получения JSON я иду исправить даты, чтобы быть объектами даты JavaSript, используя конструктор даты, который принимает строку даты 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());
    }
)

Как только у вас есть дата JavaScript, вы можете использовать все удобные и надежные методы даты, такие как toDateString, методом tolocalestring, etc.


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

проверьте дату стандарта ISO; вроде этого:

yyyy.MM.ddThh:mm

становится 2008.11.20T22:18.


Я получаю дату так:

"/Date(1276290000000+0300)/"

в некоторых примерах дата находится в несколько разных форматах:

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

etc.

поэтому я придумал следующее регулярное выражение:

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

и окончательный код:

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

надеюсь, что это помогает.

обновление: Я нашел эту ссылку от Microsoft: как сериализовать даты с JSON?

это похоже на тот, который мы все ищем.


Это неприятно. Мое решение состояло в том, чтобы разобрать "/ and /" из значения, сгенерированного ASP.NET JavaScriptSerializer, так что, хотя у JSON может не быть литерала даты, он по-прежнему интерпретируется браузером как дата, что все, что я действительно хочу:{"myDate":Date(123456789)}

пользовательский JavaScriptConverter для DateTime?

Я должен подчеркнуть точность комментария Роя Тинкера. Это не законный JSON. Это грязный, грязный хак на сервере, чтобы удалить проблема, прежде чем она станет проблемой для JavaScript. Он задушит парсер JSON. Я использовал его для отрыва от Земли, но я больше не использую это. Однако я по-прежнему считаю, что лучший ответ заключается в изменении того, как сервер форматирует дату, например, ISO, как упоминалось в другом месте.


добавить jQuery UI плагин на Вашей странице:

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

Ниже приведено довольно простое решение для разбора дат 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;
}

поздний пост, но для тех, кто искал этот пост.

представьте себе, это:

    [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 для создания "авто" дженериков. Это немного лениво, но мне нравится, и это работает. Просто Примечание: профиль-это пользовательский класс, который я создал для своего проекта веб-приложения.


решение Mootools:

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

требуется mootools-больше. Протестировано с помощью mootools-1.2.3.1-больше на Firefox 3.6.3 и IE 7.0.5730.13


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

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

настройка локализации так же просто, как добавление файлов конфигурации (вы получаете их на momentjs.com) к вашему проекту и настройке языка:

moment.lang('de');

FYI, для тех, кто использует Python на стороне сервера: datetime.значение datetime.)(ctime () возвращает строку, которая изначально анализируется с помощью "new Date ()". То есть, если вы создадите новое datetime.экземпляр datetime (например, с datetime.значение datetime.теперь), строка может быть включена в строку JSON, а затем эта строка может быть передана в качестве первого аргумента конструктору Date. Я еще не нашел никаких исключений, но и не проверял его слишком строго.


что, если .NET возвращает...

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

а затем в JavaScript...

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

Это может также помочь вам.

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