我在 Spring Boot jpa 应用程序中面临日期时间问题。
例如,在我的数据库中,我有一列
created_on
其中包含 2019-07-11 09:30:00
日期。
当我通过 JPA 获取此记录时,它会转换为 UTC。2019-07-11 09:30:00
转换为 2019-07-11 05:00:00
。
我的系统时间在 IST 中,日期也保存在 IST 的数据库中。
我使用的是mysql数据库。
在我的实体中
private Date createdOn;
数据库栏目:
created_on timestamp
服务:
@Service
@Transactional(readOnly = true)
public class EntityTypeService {
@Autowired
private IEntityTypeRepository entityTypeRepository;
public EntityType findById(Long id) {
EntityType entityType = entityTypeRepository.findById(id).orElse(new EntityType());
System.out.println(entityType.getCreatedOn());
return entityType;
}
}
存储库
@Repository
public interface IEntityTypeRepository extends CrudRepository<EntityType, Long> {
}
数据库中的日期是
2019-07-11 09:30:00
但是当我在服务上打印它时
System.out.println(entityType.getCreatedOn());
它给了我2019-07-11 05:00:00
。
这是我整个应用程序中的普遍问题。
经过大量研究,我找到了解决方案。
其实问题是因为
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
这个属性是我在我的
appication.properties
中设置的。
当我删除此属性时,后端一切正常。后端显示数据库中可用的完美时间。
但是现在当响应到达前端时,那时我的日期会转换为 UTC。
与后端一样,它显示
2020-06-03 18:56:14.0
,而当涉及前端时,它会转换为 2020-06-02T13:26:14.000+0000
。
这对我来说也是一个问题。
因此,经过更多研究,我发现当对象发送到前端时,
Jackson
默认将所有日期转换为 UTC。
这个问题的解决办法是
spring.jackson.time-zone=IST
我的数据库和系统时区是 IST,所以我也将 IST 设置为杰克逊时区,这解决了问题。
希望这个答案可以帮助别人。
在后端应用程序使用 JPA + Spring Boot 时,请确保在整个服务器配置中使用相同的时区。例如,要使用 UTC,请执行以下操作:
sudo timedatectl set-timezone UTC
(例如在 Cent 操作系统上)my.cnf
文件中(可选)spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.datasource.url=jdbc\:mysql\://localhost\:3306/my_db_name?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useLegacyDatetimeCode=false
DateTime
自动将 @JsonFormat(shape= JsonFormat.Shape.STRING, pattern="dd MMM yyyy HH:mm:ss")
值解析为字符串格式。@SpringBootApplication
@PostConstruct public void init(){ TimeZone.setDefault(TimeZone.getTimeZone("UTC")); }
这应该涵盖处理日期和时间戳时的大部分实施挑战。希望有帮助。
您可以使用
serverTimezone
设置数据库连接的时区,例如:Asia/Kolkata
并使用 useLegacyDatetimeCode=false
spring.datasource.url= = jdbc:mysql://127.0.0.1/db_name?useLegacyDatetimeCode=false&serverTimezone=Asia/Kolkata
并且不要使用遗留类
Date
而是使用现代类LocalDateTime
尽量避免使用 Date 作为时区时间戳,因为它的设计不能很好地处理这些问题。
您可以尝试使用 formatter 打印日期对象,或者使用 LocalDateTime(如果时区对您很重要,则使用 ZonedDateTime)。
您可以尝试将
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")
放在 createdOn
设置器上。