Преобразование часового пояса в Grails приводит к неправильным датам - PullRequest
0 голосов
/ 16 октября 2018

Я собираюсь разобраться с часовыми поясами в Grails (Java).Здесь используется Java 7 и Grails 2.3.7.

У меня есть веб-приложение, в котором каждому пользователю назначается timeZoneID.Если пользователь вводит дату, она состоит только из дня, месяца и года.Я хочу установить время автоматически.

Дата, введенная пользователем (например, 01.10.2018, немецкий формат), должна быть сохранена в БД (MySQL) в формате UTC.Когда дата отображается для пользователя, она форматируется в соответствии с часовым поясом пользователя.

Многие timeZoneID отлично работают с моим кодом (Европа / Берлин, Hont_Kong, ....), но Америка / Нью-Йорк дляпримера нет и я не понимаю почему.

Код для анализа и сохранения даты выглядит следующим образом:

//endDate is 31.10.2018
def format = messageService.getMessage(code: 'default.date.short.format')

//--> dd.MM.yyyy for DE and MM/dd/yy for EN
println("Use format: " + format)

SimpleDateFormat sdf = new SimpleDateFormat(format);

//set timezone (America/New_York)
sdf.setTimeZone(TimeZone.getTimeZone(user.timeZoneID))

//parse endDate
Date parsedEndDate = sdf.parse(endDate)

//create a calendar instance (e.g. America/New_York)
Calendar calendarEnd = Calendar.getInstance(TimeZone.getTimeZone(user.timeZoneID));

//set time
calendarEnd.setTime(parsedEndDate);

//set hour/minute automatically
calendarEnd.set(Calendar.HOUR_OF_DAY, 23)
calendarEnd.set(Calendar.MINUTE, 59)

//at this point it should be 31.10.2018, 23:59 (german format, timezone America/New_York)

//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))

//save the date
def obj = new Foo(date:calendarEnd).save(flush:true)

Код в моем представлении (gsp) для отображения даты имеет видследующим образом:

<g:formatDate
        timeZone="${user.timeZoneID}"
        date="${fooInstance?.calendarEnd}"
        format="${message(code: 'default.date.format', default: 'MM/dd/yyyy, hh:mm a')}"/>

Внутри БД я получаю 2018-11-01 00:59:00 Внутри моего взгляда (GSP) получается 31.10.2018, 19:59 вместо 31.10.2018, 23: 59

Большое спасибо за помощь.

1 Ответ

0 голосов
/ 16 октября 2018

Проблема в шаге преобразования:

//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))

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

Java 1.7 и более ранние версии довольно неудобны в отношении API времени, поэтому многие люди используют Joda Time.

В противном случае вы можете воспользоваться советом из этого вопроса , что приведет к чему-то вроде:

calendarEnd.add(Calendar.MILLISECOND, TimeZone.getTimeZone('UTC').getOffset(parsedEndDate.getTime())

Это не проверено и может быть неправильным, поскольку расчет смещения может быть различным

...