Как мне преобразовать из MySQL DATETIME в java.time.Мгновенно и отобразить пользователю в системном часовом поясе по умолчанию?

#java #mysql #javafx

#java #mysql #javafx

Вопрос:

Я работаю над проектом для школы, и я в полной растерянности. Вот предыстория:

Я работаю над приложением для назначения JavaFX, которое будет запускаться локально, поэтому мне не нужно беспокоиться о последствиях того, что часовой пояс на стороне сервера отличается от фактического времени пользователя. Я не могу использовать какие-либо сторонние библиотеки. В настоящее время приложение использует указатель даты и два элемента управления со списком, чтобы пользователь вводил значения даты, часа и минуты. Они хранятся в объекте назначения в переменной Instant (start) с помощью традиционных методов get / set . Я успешно записываю данные в БД из элементов управления, и мои результаты отображаются так, как я и ожидал. Если я выберу 31.06.2019 и 12:00, а затем запишу его в БД, он отобразится в БД, сохраненный в начальном столбце (который имеет тип данных DATETIME) как 2019-12-31 17:00:00. Я нахожусь в CST, поэтому мое смещение UTC составляет -5 часов. До этого момента я считаю, что все отлично.

Отсюда что-то идет не так. Я сопоставляю каждое из назначений DB объекту ObservableList, используя что-то вроде этого для каждого элемента в результирующем наборе

 Instant start = i_rs.getTimestamp("start").toInstant();
Return newAppointment(start);
  

Проверка значения переменной Instant start дает мне:

2019-12-31T17:00

как я и ожидал. Однако, похоже, я не могу успешно преобразовать это время в часовой пояс пользователя. Ближе всего я подошел к этому:

 ZonedDateTime localStartDate = currentAppointment
            .getStart()
            .atZone(ZoneId.systemDefault());
  

Но это возвращает

2019-12-31T17:00-05:00

Я также пробовал

 ZonedDateTime zdt = date.atZone(ZoneOffset.systemDefault());
  

Но это приводит к преобразованию моего времени в неправильном направлении, оставляя меня с

2019-12-31T22:00

Я работал над этой небольшой «легкой» частью более дня. Любая помощь будет с благодарностью.

Ответ №1:

 ZonedDateTime localStartDate = currentAppointment
  .getStart()
  .atZone(ZoneId.systemDefault());
  

Здесь вы говорите: «У меня есть какая-то временная метка, обрабатывайте ее как CST», поэтому она становится «17:00-05:00»

Кажется, вы храните свои временные метки в UTC (если вы этого не сделаете, я советую вам изменить свой код записи, чтобы всегда сохранять в UTC), поэтому вы должны сообщить Java об этом

 ZonedDateTime localStartDate = currentAppointment
  .getStart()
  .atZone(ZoneId.of("UTC")) // my instant is UTC
  .withZoneSameInstant(ZoneId.systemDefault()) // convert to my local zone
  

Комментарии:

1. Я не могу проголосовать, но это привело меня к правильному ответу. Похоже, я действительно не получал правильное время из БД. Простого выполнения преобразования Instant start = i_rs.getTimestamp("start").toInstant(); было недостаточно, чтобы надлежащим образом сохранить время, полученное из базы данных, как мгновенное, с точным временем, полученным из БД. Он конвертировался. Instant start = i_rs.getTimestamp("start") .toLocalDateTime() .toInstant(ZoneOffset.UTC); Это то, что меня туда привело. Спасибо за вашу помощь. Сегодня ты мой герой.

2. Примите ответ как правильный, если он вам помог или если это правильный ответ.

3. Выполнено. Извините, я не видел там флажок.