Неверное представление даты в формате json - PullRequest
2 голосов
/ 14 августа 2011

Мой код:

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
...
public void testDateSerializer() {
  final Date date = new Date();
  log.info("Today's date: " + date + " and date.getTime()=" + date.getTime());
  final JSONObject jsonObjectForDate = (JSONObject) JSONSerializer.toJSON(date);
  log.info("Same date expressed in json: " + jsonObjectForDate.toString());
}

Выход:

INFO - 2011-08-13 22:12:04,938 - TestJsonConversion.testDateSerializer(52) | Today's date: Sat Aug 13 22:12:04 EDT 2011 and date.getTime()=1313287924927
INFO - 2011-08-13 22:12:05,216 - TestJsonConversion.testDateSerializer(55) | Same date expressed in json: {"date":13,"day":6,"hours":22,"minutes":12,"month":7,"seconds":4,"time":1313287924927,"timezoneOffset":240,"year":111}

Мои вопросы:

  • Почему год = 111. Мы все еще в 2011 году, если я что-то пропустил!
  • Я нахожусь в US ETD, поэтому смещение составляет -4 часа, а не +240, что даже неправильно выражено в минутах в отношении знака смещения.

Так что я делаю не так? Это ошибка в библиотеке? Если да, то какую библиотеку я должен использовать для того же преобразования?

Спасибо

Ответы [ 3 ]

4 голосов
/ 02 июля 2013

Джода Время действительно путь.Однако, если по какой-либо причине вы застряли с java.util.Date, вы можете настроить сериализацию следующим образом:

   JsonConfig config = new JsonConfig();
   config.registerJsonValueProcessor(
        Class.forName("java.util.Date"), 
        new NiceDateJsonBeanProcessor());
   final JSONObject jsonObjectForDate = JSONSerializer.toJSON(object, jsonConfig)

Где NiceDateJsonBeanProcessor - это способ определения сериализации объекта java.util.Date.как.В моем случае я был доволен временем Unix, поэтому:

public static class NiceDateJsonBeanProcessor implements JsonValueProcessor {
    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }
    @Override
    public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
        return process(value, jsonConfig);
    }
    private Object process(Object value, JsonConfig jsonConfig) {
        if (value instanceof java.util.Date) {
            java.util.Date d = (java.util.Date) value;
            return d.getTime();
        }
        return null;
    }
}
1 голос
/ 14 августа 2011

Это может помочь посмотреть на источник JSONObject здесь

По сути, он обрабатывает ваш переданный объект Date как Java Bean.Таким образом, он перебирает отражение, все методы «get *» в вашем объекте даты и это то, что вы видите в вашем JSONObject.

Все методы get объекта java.util.Date устарела, и вы видите странность, например год 111 вместо 2011.

Если вы хотите передавать объекты даты через JSON, вы можете рассмотреть возможность передачи их как объектов String, отформатированных определенным образом, ИЛИ использовать Calendar.

1 голос
/ 14 августа 2011

На самом деле такое поведение вполне ожидаемо, верите или нет.

Вы используете класс java.util.Date.Этот класс имеет в основном кучу устаревших методов.Смотрите документацию здесь:

http://download.oracle.com/javase/6/docs/api/java/util/Date.html

Теперь ваш сериализатор JSON просто собирается создать строку JSON из методов получения в вашем объекте Java.Посмотрите на получателей в классе java.util.Date.Большинство из них устарели, и вы можете понять, почему.Год относится к 1900 году!Смещение часового пояса равно в минутах в обратном направлении.

Чтобы приложение работало так, как вы ожидаете, ознакомьтесь с предупреждениями об устаревании для Date, в которых указывается использовать GregorianCalendar.Тем не менее, я рекомендую использовать JodaTime .Небольшая кривая обучения, но это того стоит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...