#java #spring-boot #maven #datetime #rest
Вопрос:
Я создал один простой класс модели User
. Я использовал здесь Util date.
class User{
private int id;
private String name;
private Date createdAt;
}
При вызове пользовательского post API я просто делаю setCreatedAt(new Date)
это.
Проблема в ответе, я получаю createdAt как -5.30 от фактического времени. Дополнительный метод преобразования времени не вызывается.
Например, я нажимаю на сообщение, созданное пользователем API 28-10-2021 11:30:00
, которое я вижу в журналах. Но когда он возвращает ответ почтальону, он показывает 28-10-2021 06:00:00
время. В коде нет метода преобразования времени. Я проверил возвращаемый объект в инструкции return в режиме отладки, даже если он отображается 28-10-2021 11:30:00
.
- Я хотел знать, где происходит это преобразование. И как это остановить.
- Если это проблема с библиотекой datetime, то какую из них мне следует использовать.
Extra information:
* My system timezone is in UTC.
* I am using ubuntu.
* Creating restFull APIs(JaxRs)
РЕДАКТИРОВАТЬ 1:
клиент и сервер находятся на одном компьютере (часовой пояс UTC). Для клиента я использую Postman.
URL: [POST] / user
Тело запроса:
{
"name": "XYZ"
}
Фактический ответ:
{
"id": 1,
"name": "XYZ",
"createdAt: "28-10-2021 06:00:00"
}
Ожидаемый ответ:
{
"id": 1,
"name": "XYZ",
"createdAt: "28-10-2021 11:30:00"
}
Комментарии:
1. Кажется, это простая причина: клиент и сервер используют разные часовые пояса, которые влияют на преобразование между объектом date и текстовым представлением, используемым API. Можете ли вы добавить подробную информацию об API?
2. Сервер и клиент находятся на одном компьютере (UTC). Для получения более подробной информации я редактирую сообщение. Пожалуйста, дайте мне знать, что еще требуется.
3. Похоже, API интерпретирует время как UTC, но Postman может использовать IST. «Клиент и сервер находятся на одном компьютере (часовой пояс UTC)». — они все еще могут быть настроены по-разному.
4. Ваше обновление, похоже, поддерживает это: дата, похоже, создается в UTC, но ваши системные часы будут в ITC (или что бы вы ни использовали для определения ожидаемого времени). Итак, 11:30 IST — это 06:00 UTC (в тот же момент), и, таким образом, преобразование даты в строку UTC возвращает 06:00.
Ответ №1:
При вызове пользовательского post API я просто выполняю setCreatedAt(новая дата).
Похоже, вы не установили часовой пояс при создании экземпляра java.util.Date
По умолчанию он будет установлен как UTC независимо от вашего системного часового пояса. Вы можете использовать https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html вместо этого.
final TIMEZONE = ""; // need to set the timezone here
SimpleDateFormat formatter = new SimpleDateFormat("dd-M-yyyy hh:mm:ss", Locale.ENGLISH);
formatter.setTimeZone(TimeZone.getTimeZone(TIMEZONE));
String dateInString = "28-10-2021 11:30:00";
Date date = formatter.parse(dateInString);
Ответ №2:
Могут быть аннотации JsonFormat, которые имеют проблемы с часовым поясом. Пожалуйста, проверьте ссылку для получения более подробной информации по этому вопросу.проблема с привязкой Джексона к данным, переопределяющая часовой пояс в ObjectMapper, также не сработала. Вы можете сослаться на решаемый пример, внедрив пользовательский десериализатор даты, как показано ниже:
@Component
public class CustomDateDeserializer extends StdDeserializer<Date> {
private static final long serialVersionUID = 1L;
private SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); // specify your specific timezone
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Date deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String date = jsonparser.getText();
try {
return formatter.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
Кроме того, добавьте десериализатор в метод setter в свойствах компонента.
@JsonDeserialize(using = CustomDateDeserializer.class)
public void setReturnDateTime(Date returnDateTime) {
this.returnDateTime = returnDateTime;
}