У меня есть следующий код, который я хочу перенести на 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) кажется наиболее близким эквивалентом org.joda.time.DateTime.withZone(..) для java.time.OffsetDateTime. Или, может быть, вы намеревались использовать java.time.Instant, и тогда вам нужно было бы использовать метод atZone(ZoneId).
Хорошо, но для atZoneSameInstant(.....) какой аргумент мне нужно передать, который будет таким же, как DateTimeZone.UTC?
Вы хотите перейти с библиотеки Joda-Time на классы java.time, встроенные в Java 8+? Если да, то так и скажи. Отредактируйте текст вашего вопроса.
Я хочу перенести код на java 17, но максимально сохранить ту же функциональность. Не могли бы вы подсказать мне, как это сделать правильно, пожалуйста?
Вы можете использовать ZoneOffset.UTC или ZoneId.of("UTC")
Тем не менее, переход на Java 17 не имеет ничего общего с переходом на Jodatime. Классы java.time существуют с Java 8, и, насколько мне известно, Jodatime отлично работает на Java 17.
Я обновил пост с вашим предложением, но теперь получаю ошибку: Cannot resolve method 'print(ZonedDateTime)'
@PeterPenzov Просто пытаться мигрировать, пытаясь заменить типы и задавать вопрос или комментировать каждую полученную ошибку компиляции, не является плодотворным упражнением. Изучите фактический API, и вы увидите, что у java.time.format.DateTimeFormatter нет метода print (вы, вероятно, хотите format).
Извините, но код очень важен, и у меня нет большого опыта работы с DateTime. Я получаю Cannot resolve method 'format' in 'DateTimeFormatter' Нет формата метода.
Тогда вы, вероятно, все еще используете DateTimeFormatter Joda-Time, а не Java. И если код настолько критичен, то либо не мигрируйте с Joda-Time, либо это должен сделать кто-то с большим опытом работы с Joda-Time и API java.time. Насколько мне известно, он отлично работает на Java 17, так что это не может быть причиной, по которой вы переходите с него.
Да, ты прав. Последний вопрос, какой форматтер мне нужно использовать для времени Java?
.withOffsetSameInstant(ZoneOffset.UTC)
?
log
— сущность (общедоступный класс Log {...})
Я запутался, потому что вы пытаетесь вызвать log.setTimestamp(), но в вашей Log сущности я не вижу никакого setTimestamp метода? Какой тип имеет его параметр?
Вы форматируете строку yy-mm-dd'T'HH:mm:ss'Z' странно и неправильно (как в старом, так и в новом коде). Он пытается соответствовать ISO 8601, но в ISO 8601 год с двумя цифрами не допускается. Первая строчная буква mm неверна, как объяснено в ответе. Ставить Z в кавычки тоже неправильно. Это смещение, поэтому отформатируйте смещение от даты и времени. Для создания правильного ISO 8601 вам не нужна строка шаблона формата, поскольку и Joda-Time, и java.time изначально создают ISO 8601.
Таким образом, чтобы создать строку, предполагая, что auditLog является Log: auditLog .getInsertedDate() .withOffsetSameInstant(ZoneOffset.UTC) .toString(). Или, если вам не нужны доли секунды: ... .withOffsetSameInstant(ZoneOffset.UTC) .truncatedTo(ChronoUnit.SECONDS) .toString().
(Возможно, вы уже это знаете), для лучшего ответа на ваш вопрос (1) предоставьте полный воспроизводимый код (минимальный воспроизводимый пример) (2) добавьте все правильные теги.
Прежде всего, похоже, что ваш формат времени не тот, что вы хотели.
"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?
java.time
(JSR-310).
Вы имеете в виду atZoneSameInstant(ZoneId)