Javascript и Java Date JSON сериализация - PullRequest
15 голосов
/ 18 января 2012

У меня есть объект javascript со свойством Date , которое преобразуется в JSON с использованием JSON.stringify

Я по Гринвичу + 4 часовых пояса (Россия / Москва)

Например, 5 Jan 2012 конвертируется в 2012-01-04T20:00:00.000Z

5 Jan 1975 преобразуется в 1975-01-04T20:00:00.000Z

Но в 1975 году это был часовой пояс GMT + 3, поскольку переход на летнее время в России был отменен в 2011 году. Поэтому, когда дело доходит до сервера (java), оно десериализуется следующим образом:

2012-01-04T20:00:00.000Z стало 5 Jan 2012 00:00 - ОК

1975-01-04T20:00:00.000Z стало 4 Jan 1975 23:00 - НЕПРАВИЛЬНО!

Каков рекомендуемый способ преобразования объекта Date в JSON в Javascript?

Ответы [ 6 ]

14 голосов
/ 13 августа 2013

Я предпочитаю придерживаться формата даты javascripts ISO 8601, при правильном разборе он будет автоматически обрабатывать разницу часовых поясов.

В java вы можете разобрать строковую дату JSON javascript следующим образом:

String iso8601Date = "2013-08-13T14:15:00.000Z";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date parsedDate = formatter.parse(iso8601Date);

Если превратить его обратно в строку, у вас будет что-то вроде этого

//"2013-08-13T16:15:00.000+02:00"
String formattedDate = formatter.format(parsedDate);

Для анализа JSON я использую FlexJson, который вы можете настроить следующим образом.

//Serializing to JSON
DateTransformer dateTransformer = new DateTransformer("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
new JSONSerializer().transform(dateTransformer, Date.class).serialize(object);
//deserialize From JSON (replace object by java class)
JSONDeserializer<..Object..>().use(Date.class, dateTransformer).deserialize(json);
12 голосов
/ 18 января 2012

Я бы посоветовал передавать дату / время, используя их секунды начиная с обозначения эпохи, а точнее количество секунд, прошедших с начала эпохи Unix (1 января 1970 г. 00:00 по Гринвичу). Если вы не знакомы с этим, здесь приведен пример конвертера: http://www.epochconverter.com/

Это имеет несколько преимуществ:

  • Относится к одному и тому же моменту времени независимо от часового пояса. Это помогает сохранять время независимо от ошибок часового пояса (хотя, конечно, они должны быть правильно введены в первую очередь).
  • Это единственный не осуждаемый конструктор (кроме конструктора без параметров) в java.util.Date, см. (getTime() тоже). (Обратите внимание, что для этого используются миллисекунды.)
  • JavaScript может довольно легко построить дату из него (например, new Date(1000 * 1326894706)). (Обратите внимание, что для этого используются миллисекунды.)
  • Если это имеет значение, он всегда будет немного меньше (с точки зрения размера данных в сериализации JSON), чем любой из "yyyy-MM-dd HH:mm:ss".
  • Если вы хотите, чтобы часовой пояс отображался и ассоциировался с этим номером, вы всегда можете добавить дополнительное поле в свое представление. { "datetime": 1326894706, "tz": "GMT" } по-прежнему короче { "datetime": "18 Jan 2012 13:51:46 GMT" }.

Учитывая, что легко получить Date экземпляров из этого в Java и JavaScript, вы можете затем использовать DateFormatter для преобразования его в / из текста в Java. Для JavaScript использование библиотеки, такой как Формат даты , поможет вам правильно отобразить ее на странице (например, с чем-то вроде new Date(val * 1000).format("yyyy-mm-dd HH:MM")).

1 голос
/ 08 июня 2015

Если вы используете Spring Framework, вы можете использовать аннотации @JsonSerialize(using = CustomLocalDateSerializer.class) и @JsonDeserialize(using = ISO8601LocalDateDeserializer.class). Он правильно проанализирует ваш javascript Date.

Пример:

public class product {

    @NotNull
    private Long id;

    @NotNull
    private String name;

    @JsonSerialize(using = CustomLocalDateSerializer.class)
    @JsonDeserialize(using = ISO8601LocalDateDeserializer.class)
    private LocalDate date;

    // getter and setter...
}
0 голосов
/ 28 марта 2019

Эта тема довольно старая.В настоящее время, с Java 8, вы должны использовать ZonedDateTime в вашей форме dto.Используя spring-mvc, Джексон будет правильно отображать формат ISO (например: "2019-03-27T22:05:42.763Z") на ZonedDateTime.

Однако метод Date.toISOString всегда устанавливает часовой пояс на utc, поэтому ваша десериализованная зона ZonedDateTime всегда будетустановить в UTC.Это может быть проблемой, если вам нужна зона на стороне сервера.Допустим, например, что вам нужно отправить клиенту электронное письмо с датой, которую он / она только что отправил через форму: вы хотите использовать ту же зону.

Если вы хотите передать часовой пояс и соблюдатьФормат ISO, вы должны использовать lib как moment.js для форматирования дат в javascript.А потом при сериализации:

moment().format('YYYY:MM:DDTHH:mm:ssZ') // "2019:03:27T23:06:11+01:00"
0 голосов
/ 18 января 2012

JSON не поддерживает Date, все парсеры / сериализаторы используют toString или что-то в этом роде. Вы можете сериализовать / десериализовать даты.
Поскольку в Javascript нет подходящего средства форматирования даты, самое простое решение - преобразовать дату в long. Но если вы хотите прочитать, что происходит, я рекомендую http://www.datejs.com/ и форматировать даты как гггг-мм-дд ЧЧ: мм: сс

0 голосов
/ 18 января 2012

Я лично конвертировал бы их в String в Java, используя что-то вроде этого:

String theDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

И затем String сериализуется.В javascript вы просто разбираете это.

...