Десериализация клиентских дат AJAX JSON

Учитывая следующее представление даты JSON:

"/Date(1221644506800-0700)/"

Как вы десериализуете это в форму типа даты JavaScript?

Я пробовал использовать MS AJAX JavaScrioptSerializer, как показано ниже:

Sys.Serialization.JavaScriptSerializer.deserialize("/Date(1221644506800-0700)/")

Однако все, что я получаю, - это буквальная дата строки.

Возможно, вы используете jQuery? Проверьте мое сообщение в блоге об автоматическом преобразовании дат, чтобы вам не приходилось делать это вручную. erraticdev.blogspot.com/2010/12/…

Robert Koritnik 27.12.2010 18:51

Смотрите мои комментарии ниже. Код вашего блога не работает на датах, предшествующих эпохе.

Josh Pearce 28.11.2011 22:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
36
2
21 112
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Большое число - это стандартное время JS.

new Date(1221644506800)

Среда, 17 сентября 2008 г., 19:41:46 GMT + 1000 (EST)

Значение JSON - это строка, число, объект, массив, true, false или null. Так что это всего лишь строка. Официального способа представления дат в JSON не существует. Этот синтаксис взят из реализации ajax asp.net. Другие используют формат ISO 8601.

Вы можете разобрать это так:

var s = "/Date(1221644506800-0700)/";
var m = s.match(/^/Date\((\d+)([-+]\d\d)(\d\d)\)/$/);
var date = null;
if (m)
  date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]);

Мой метод toJson выдавал сериализованные даты как «\ / Date (1251795070160) \ /», которые ваш код не анализирует. Позже я выясню почему, просто опубликую здесь для других

CVertex 01.09.2009 16:21

+1, чтобы прояснить, каким может быть значение JSON и что даты не являются одним из них, а являются настраиваемым форматом.

René 29.09.2011 18:20

Это регулярное выражение не будет работать для дат до эпохи, которые имеют отрицательное значение. Вам понадобится это: //Date\((-?\d+)(?:-\d+)?\)//i

Josh Pearce 28.11.2011 20:17

@Sjoerd: Вам нужно добавить часовой пояс или вычесть его, чтобы преобразовать его в UTC? Я запутался, потому что, если я вижу время как 1/1/2000 0:0:0 +0500 (я думаю), мне нужно вычесть 5 часов, чтобы получить время UTC.

Salman A 16.05.2012 20:42

Вы можете вернуться к parseInt, если часовой пояс не указан if (date == null) date = new Date(parseInt(s.substring(6, s.length - 2), 10));

Gideon Mulder 22.06.2017 11:18

Регулярное выражение, используемое в методе десериализации ASP.net AJAX, ищет строку, которая выглядит как «/ Date (1234) /» (сама строка действительно должна содержать кавычки и косые черты). Чтобы получить такую ​​строку, вам нужно будет экранировать символы кавычек и обратной косой черты, чтобы код javascript для создания строки выглядел как "\" \ / Date (1234) \ / \ "".

Это сработает.

Sys.Serialization.JavaScriptSerializer.deserialize("\"/Date(1221644506800)/\"")

Это немного странно, но я обнаружил, что мне нужно сериализовать дату, затем сериализовать строку, возвращаемую из нее, а затем один раз десериализовать на стороне клиента.

Что-то вроде этого.

Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer();
string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now)));
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true);

Проблема с этим методом заключается в том, что он не смотрит на часовой пояс: Sys.Serialization.JavaScriptSerializer.deserialize ("\" \\ / Dat‌ e (1221644506800 + 0200‌) \\ / \ "") Результат будет тот же как: Sys.Serialization.JavaScriptSerializer.deserialize ("\" \\ / Dat‌ e (1221644506800 + 0300‌) \\ / \ "")

Gideon Mulder 22.06.2017 11:10
Ответ принят как подходящий

Если вы знаете, что строка определенно является датой, я предпочитаю сделать это:

 new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))

Это сработало для меня, мой метод ToJson сериализовал DateTimes как "\ / Date (1251795081950) \ /"

CVertex 01.09.2009 16:24

Спасибо. var date = new Date(parseInt(jsonDate.substr(6))); тоже работает.

Brian Chavez 04.03.2011 03:57

Для тех, кто не хочет использовать Microsoft Ajax, просто добавьте функцию-прототип в строковый класс.

Например.

    String.prototype.dateFromJSON = function () {
    return eval(this.replace(//Date\((\d+)\)//gi, "new Date()"));
};

Не хотите использовать eval? Попробуйте что-нибудь простое, например

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

Кстати, раньше я думал, что Microsoft вводит в заблуждение, используя этот формат. Однако спецификация JSON не очень ясна, когда дело доходит до определения способа описания дат в JSON.

Это регулярное выражение не будет работать для дат до эпохи, которые имеют отрицательное значение. Вам понадобится это: //Date\((-?\d+)(?:-\d+)?\)//i

Josh Pearce 28.11.2011 20:28

Бертран Лерой, который работал над ASP.NET Atlas / AJAX, описал дизайн вывода JavaScriptSerializer DateTime и раскрыл происхождение таинственных косых черт в начале и в конце. Он дал такую ​​рекомендацию:

run a simple search for "/Date((\d+))/" and replace with "new Date()" before the eval (but after validation)

Я реализовал это как:

var serializedDateTime = "/Date(1271389496563)/";
document.writeln("Serialized: " + serializedDateTime + "<br />");

var toDateRe = new RegExp("^/Date\((\d+)\)/$");
function toDate(s) {
    if (!s) {
        return null;
    }
    var constructor = s.replace(toDateRe, "new Date()");
    if (constructor == s) {
        throw 'Invalid serialized DateTime value: "' + s + '"';
    }
    return eval(constructor);
}

document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");

Это очень близко ко многим другим ответам:

  • Используйте заякоренное регулярное выражение, как это сделал Шорд Висшер - не забывайте ^ и $.
  • Избегайте string.replace и параметров 'g' или 'i' в вашем RegEx. "/ Date (1271389496563) // Date (1271389496563) /" вообще не должно работать.

Очень хороший ответ .... позор, я нашел его в конце списка вопроса.

GordonB 29.04.2010 15:37

Это регулярное выражение не будет работать для дат до эпохи, которые имеют отрицательное значение. Вам нужно что-то вроде этого: //Date\((-?\d+)(?:-\d+)?\)//i

Josh Pearce 28.11.2011 20:18

Фактически, momentjs поддерживает такой формат, вы можете сделать что-то вроде:

    var momentValue = moment(value);

    momentValue.toDate();

Это возвращает значение в формате даты javascript

Другие вопросы по теме