JPA结合PostgreSQL时CURRENT_TIMESTAMP的取值与格式化问题
JPA TypedQuery中CURRENT_TIMESTAMP的时区疑问与格式化方案
问题1:CURRENT_TIMESTAMP取的是数据库还是应用服务器的时间?
答案很明确:它取的是数据库服务器(巴黎时区)的时间。
你写的是JPQL查询,JPQL里的CURRENT_TIMESTAMP并不是Java应用端生成的时间,而是会被JPA框架转换成对应数据库的原生时间函数(比如MySQL用CURRENT_TIMESTAMP(),Oracle用SYSTIMESTAMP),最终在数据库服务器上执行计算。这就是为什么你看到和日本时区的应用服务器有2小时时差——巴黎和日本的时区差刚好是2小时,完全对应你遇到的偏差。
问题2:如何将CURRENT_TIMESTAMP格式化为YYYY-MM-DD HH:mm:SS?
分两种场景给你实用方案:
场景1:在JPQL查询条件中直接格式化(推荐用于查询过滤)
JPQL本身没有通用的时间格式化函数,不过你可以用JPA 2.1+支持的FUNCTION()语法,调用数据库原生的格式化函数来实现:
- 如果你用的是MySQL/MariaDB:
String query = "select s from Student s where (b.beginDate + b.beginTime) < FUNCTION('DATE_FORMAT', CURRENT_TIMESTAMP, '%Y-%m-%d %H:%i:%s')"; - 如果你用的是Oracle数据库:
要是你用的JPA版本低于2.1,那只能改用原生SQL查询(String query = "select s from Student s where (b.beginDate + b.beginTime) < FUNCTION('TO_CHAR', CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS')";EntityManager.createNativeQuery())来直接写数据库的格式化语句了。
场景2:在Java应用端格式化(适合查询结果展示)
如果只是需要把查询出来的时间值格式化展示,不需要用在查询条件里,那可以拿到Timestamp对象后用Java的DateTimeFormatter处理,记得要和数据库时区保持一致:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); // 指定巴黎时区,和数据库服务器时区对齐 LocalDateTime dbTime = LocalDateTime.now(ZoneId.of("Europe/Paris")); String formattedTime = formatter.format(dbTime);
内容的提问来源于stack exchange,提问作者Tbtrungdn
相关产品推荐
相关产品推荐

