Не удается разрешить метод withZone в OffsetDateTime

У меня есть следующий код, который я хочу перенести на Java 17:

Зависимость Gradle:

implementation 'org.jadira.usertype:usertype.core:7.0.0.CR1'

Сущность:

    import org.joda.time.DateTime;

    @Entity
    @Table(name = "logs")
    public class Log {
    
      @Column(name = "inserted_date")
      @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
      private DateTime insertedDate;
    }


.....

DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yy-mm-dd'T'HH:mm:ss'Z'");

log.setInsertedDate(DateTime.now());
dateFormatter.print(log.getInsertedDate().withZone(DateTimeZone.UTC)));

Я обновил код до этого:

Сущность:

    import java.time.OffsetDateTime;

    @Entity
    @Table(name = "logs")
    public class Log {
    
      @Column(name = "inserted_date")
      private OffsetDateTime insertedDate;
    }


.....

DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yy-mm-dd'T'HH:mm:ss'Z'");

log.setInsertedDate(OffsetDateTime.now());
dateFormatter.print(log.getInsertedDate().withZone(DateTimeZone.UTC)));

Но получаю ошибку Cannot resolve method 'withZone' in 'OffsetDateTime'. Знаете ли вы, как правильно обновить метод withZone?

редактировать: я пробовал это

от: log.setTimestamp(dateFormatter.print(auditLog.getInsertedDate().withZone(DateTimeZone.UTC)));

кому: log.setTimestamp(dateFormatter.print(auditLog.getInsertedDate().atZoneSameInstant(ZoneOffset.UTC)));

Я получаю для этой строки: auditLog.getInsertedDate().atZoneSameInstant(ZoneOffset.UTC) ошибка:

Cannot resolve method 'print(ZonedDateTime)'

Можете ли вы посоветовать, как это решить?

Вы имеете в виду atZoneSameInstant(ZoneId)

Mark Rotteveel 12.02.2023 18:23

извините, вы можете уточнить больше?

Peter Penzov 12.02.2023 18:25

Метод atZoneSameInstant(ZoneId) кажется наиболее близким эквивалентом org.joda.time.DateTime.withZone(..) для java.time.OffsetDateTime. Или, может быть, вы намеревались использовать java.time.Instant, и тогда вам нужно было бы использовать метод atZone(ZoneId).

Mark Rotteveel 12.02.2023 18:26

хорошо, но для atZoneSameInstant(.....) какой аргумент мне нужно передать, который будет таким же, как DateTimeZone.UTC?

Peter Penzov 12.02.2023 18:28

Вы хотите перейти с библиотеки Joda-Time на классы java.time, встроенные в Java 8+? Если да, то так и скажи. Отредактируйте текст вашего вопроса.

Basil Bourque 12.02.2023 18:47

Я хочу перенести код на java 17, но максимально сохранить ту же функциональность. Не могли бы вы подсказать мне, как это сделать правильно, пожалуйста?

Peter Penzov 12.02.2023 19:18

Вы можете использовать ZoneOffset.UTC или ZoneId.of("UTC")

Mark Rotteveel 13.02.2023 10:01

Тем не менее, переход на Java 17 не имеет ничего общего с переходом на Jodatime. Классы java.time существуют с Java 8, и, насколько мне известно, Jodatime отлично работает на Java 17.

Mark Rotteveel 13.02.2023 10:02

Я обновил пост с вашим предложением, но теперь получаю ошибку: Cannot resolve method 'print(ZonedDateTime)'

Peter Penzov 13.02.2023 17:01

@PeterPenzov Просто пытаться мигрировать, пытаясь заменить типы и задавать вопрос или комментировать каждую полученную ошибку компиляции, не является плодотворным упражнением. Изучите фактический API, и вы увидите, что у java.time.format.DateTimeFormatter нет метода print (вы, вероятно, хотите format).

Mark Rotteveel 13.02.2023 17:04

Извините, но код очень важен, и у меня нет большого опыта работы с DateTime. Я получаю Cannot resolve method 'format' in 'DateTimeFormatter' Нет формата метода.

Peter Penzov 13.02.2023 17:08

Тогда вы, вероятно, все еще используете DateTimeFormatter Joda-Time, а не Java. И если код настолько критичен, то либо не мигрируйте с Joda-Time, либо это должен сделать кто-то с большим опытом работы с Joda-Time и API java.time. Насколько мне известно, он отлично работает на Java 17, так что это не может быть причиной, по которой вы переходите с него.

Mark Rotteveel 13.02.2023 17:10

Да, ты прав. Последний вопрос, какой форматтер мне нужно использовать для времени Java?

Peter Penzov 13.02.2023 17:32
.withOffsetSameInstant(ZoneOffset.UTC)?
Ole V.V. 19.02.2023 21:56
log — сущность (общедоступный класс Log {...})
Peter Penzov 19.02.2023 22:30

Я запутался, потому что вы пытаетесь вызвать log.setTimestamp(), но в вашей Log сущности я не вижу никакого setTimestamp метода? Какой тип имеет его параметр?

Ole V.V. 20.02.2023 05:19

Вы форматируете строку yy-mm-dd'T'HH:mm:ss'Z' странно и неправильно (как в старом, так и в новом коде). Он пытается соответствовать ISO 8601, но в ISO 8601 год с двумя цифрами не допускается. Первая строчная буква mm неверна, как объяснено в ответе. Ставить Z в кавычки тоже неправильно. Это смещение, поэтому отформатируйте смещение от даты и времени. Для создания правильного ISO 8601 вам не нужна строка шаблона формата, поскольку и Joda-Time, и java.time изначально создают ISO 8601.

Ole V.V. 20.02.2023 05:23

Таким образом, чтобы создать строку, предполагая, что auditLog является Log: auditLog .getInsertedDate() .withOffsetSameInstant(ZoneOffset.UTC) .toString(). Или, если вам не нужны доли секунды: ... .withOffsetSameInstant(ZoneOffset.UTC) .truncatedTo(ChronoUnit.SECONDS) .toString().

Ole V.V. 20.02.2023 05:29

(Возможно, вы уже это знаете), для лучшего ответа на ваш вопрос (1) предоставьте полный воспроизводимый код (минимальный воспроизводимый пример) ​​(2) добавьте все правильные теги.

Ole V.V. 20.02.2023 05:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
19
155
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего, похоже, что ваш формат времени не тот, что вы хотели.

"yy-mm-dd'T'HH:mm:ss'Z'" будет означать формат, который печатает:
год-минуты-дни'T'часы(24-часовой формат):минуты:секундыZ
пример: 23-48-19T14:48:17Z

Я предполагаю, что вы хотите следить за годами с месяцем года, поэтому формат должен быть:
"гг-мм-дд'Т'ЧЧ:мм:сс'Z'"
пример: 23-02-19T14:48:17Z

Чтобы узнать больше о создании шаблонов для форматирования, обратитесь к разделу «Шаблоны для форматирования и синтаксического анализа» в java time api docs



Теперь, что касается вашего вопроса,
Кажется, вы смешиваете библиотеку времени joda с API даты и времени Java. Написанный исключительно с помощью API даты и времени Java, ваш код должен выглядеть примерно так:

import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;


DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yy-MM-dd'T'HH:mm:ss'Z'");
log.setInsertedDate(OffsetDateTime.now());
log.setTimestamp(dateFormatter.format(auditLog.getInsertedDate().atZoneSameInstant(ZoneId.of("UTC"))));

PS: я знаю, что работа с объектами даты и времени может быть разочаровывающей и запутанной в Java, особенно потому, что раньше было несколько способов сделать это. Я бы порекомендовал прочитать учебники по Java Date Time API, чтобы лучше понять и всегда использовать его (при написании на Java 8+), чтобы избежать путаницы.

Спасибо за ваш ответ. Один дополнительный вопрос, который мне не ясен. Должен ли я использовать joda time library или java date time api из Java 17?

Peter Penzov 19.02.2023 19:28
Домашняя страница Joda-time четко отвечает на эту часть: обратите внимание, что Joda-Time считается в значительной степени «завершенным» проектом. Серьезных доработок не планируется. Если вы используете Java SE 8, перейдите на java.time (JSR-310).
Ole V.V. 19.02.2023 22:02

Другие вопросы по теме