Как сохранить часовые пояса при использовании Groovy JsonBuilder?

Groovy JsonBuilder, похоже, вообще не преобразует часовые пояса в даты в строку JSON. Или, точнее, он всегда использует GMT. Например, следующий код должен печатать дату как полночь 03 февраля 2001 г., GMT +2. Но вместо этого он печатает 2001-02-02T22:00:00+0000, то есть ту же дату минус 2 часа, как если бы она была по Гринвичу.

Есть ли ошибка в JsonBuilder или это "известная функция", которую необходимо учитывать при использовании API?

import groovy.json.JsonBuilder

def c = new GregorianCalendar( new Locale( "fi", "FI" ) ) // GMT+2, no DST by default
c.set( 2001, 1, 3, 0, 0 ) // 2001-02-03T00:00:xx, xx is current seconds. Not set as irrelevant


println ( new JsonBuilder( [ date: c.getTime() ] ) ).toString()

person kaskelotti    schedule 08.09.2014    source источник


Ответы (1)


Глядя на JsonBuilder, он выглядит как ошибка или неподдерживаемая функциональность.

При звонке

( new JsonBuilder( [ date: c.getTime() ] ) ).toString()

Он статически вызывает JsonOutput.toJson(content). После некоторой логики он вызывает JsonOutput.writeObject, который выясняет, что мы имеем дело с датой (или календарем, если вы опустите вызов getTime).

Затем он вызывает JsonOutput.writeDate, который ссылается на частный статический формат даты, основанный на DateFormatThreadLocal();

DateFormatThreadLocal создает SimpleDateFormat с локалью США и часовым поясом по Гринвичу.

Я не смог найти способ указать свой собственный формат даты для построителя, поэтому я предлагаю вам предварительно отформатировать даты и предоставить их в виде строки для построителя:

 def fiTimeZone = TimeZone.getTimeZone("GMT+2")
 def formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", new Locale( "fi", "FI" ))
 formatter.setTimeZone(fiTimeZone)

 def c = new GregorianCalendar( new Locale( "fi", "FI" ) ) 
 c.set( 2001, 1, 3, 0, 0 ) // 2001-02-03T00:00:xx, xx is current seconds. Not set as irrelevant
 def formatedDate = formatter.format(c.getTime())
 println ( new JsonBuilder( [ date: formatedDate ] ) )

вывод {"дата":"2001-02-03T00:00:42+0200"}

Обратите внимание на проблемы безопасности потоков с SimpleDateFormat, см. здесь

person Haim Raman    schedule 09.09.2014
comment
Спасибо за подтверждение, что моя логика верна и с JsonBuilder действительно что-то есть. Вместо пользовательского форматирования я решил изменить базовую библиотеку JSON, спасибо за идею. Кстати, Jacson не работает с той же проблемой, но Jacson-jr работает нормально. - person kaskelotti; 10.09.2014