【发布时间】:2017-12-03 11:49:59
【问题描述】:
我正在使用带有 LocalDate 和 LocalDateTime 的 Spring Boot 1.5.4、Hibernate 5.2.10、Spring Data REST、HATEOAS、JDK8。 我的电脑在 CEST 时区,但我希望应用程序在 UTC 中工作,所以我在 application.properties 中设置:
spring.datasource.url=jdbc:mysql://localhost:3306/database?useLegacyDatetimeCode=false&serverTimezone=UTC&useSSL=true
spring.jpa.hibernate.jdbc.time_zone = UTC
根据article,我不想更改 JVM 的时区,因为这似乎不是最佳实践。
Spring Data REST 公开了我的存储库,我使用 Swagger2 来提供一个很好的接口来使用 API。 当我尝试一个端点时,我看到如下内容:
{
"_embedded": {
"dailyCodes": [
{
"sid": "d495cdaa-14f2-44cb-a98f-8aa6ddd43d91",
"createdDate": "2017-06-28T16:20:01",
"lastModifiedDate": "2017-06-28T16:20:01",
"lastModifiedBy": "admin",
"date": "2017-06-28",
"code": "js",
"new": false,
"_links": {
"self": {
"href": "http://localhost:8080/api/v1/dailyCodes/1"
},
"dailyCode": {
"href": "http://localhost:8080/api/v1/dailyCodes/1"
}
}
}
就像您可以看到日期时间格式很好,并且即使在数据库中实际时间是 14:20:01,它也会显示 CEST 时间。 我想这是错误的,因为我的 REST API 应该在 UTC 中工作。
我怎样才能达到这个结果?
总是在同一个主题上,我有一个 REST 端点(由 Spring Data REST 公开)使用 LocalDate 参数进行搜索;我正在使用
@Transactional
@PreAuthorize("isAuthenticated()")
public interface DailyCodeRepository extends PagingAndSortingRepository<DailyCode, Long> {
@Query("SELECT d FROM DailyCode d WHERE (:code IS NULL or code=:code) AND (:from IS NULL OR date>=:from) AND (:to IS NULL OR date<=:to)")
public Page<DailyCode> findAllWithParameter(@Param("code") @RequestParam(value = "code", required = false) String code,
@Param("from") @RequestParam(value = "from", required = false) LocalDate from,
@Param("to") @RequestParam(value = "to", required = false) LocalDate to, Pageable pageable);
}
在这种情况下,我还有一件奇怪的事情:如果我调用端点传递参数,它们在服务器中到达的时间会少 1 天。此外,接受的日期模式似乎是我的语言环境(意大利语)的 JDK 默认值,但我想这不是最佳实践。
是否有最佳做法可以避免双向日期/时间参数出现问题?
【问题讨论】:
-
我对 LocalDate 等不是很熟悉。但是jdbc.time_zone参数只影响VM内部和数据库之间的转换。在JDBC驱动中,会有一个Date对象,基本上是era毫秒,没有任何时区信息。通常,当它被格式化为(人类可读的)字符串时,这将根据格式化程序中指定的时区或默认时区来完成。
-
但是,当它被格式化为作为日期写入数据库时,jdbc.time_zone 参数用于此转换。我不确定当 Date 对象转换为 LocalDate 时会发生什么,但我假设您遇到的问题在于那里,而不是 VM 和 DB 之间的转换。
标签: java spring rest spring-mvc spring-data-rest