oracle获取当前时间用sysdate还是systimestamp?时间类型踩坑记录

907 阅读2分钟

一、背景介绍

代码中有一条sql,查询条件是endtimestamp < sysdate,endtimestamp是一个字段,记录的是保存数据时间,sysdate是oracle获取执行sql时间的函数。
按理说肯定是先保存然后再查,查一定再插入之后,但如果有这个查询条件,就不能查到数据。
排查时,把查询条件替换为endtimestamp < systimestamp,就能查到数据了,都是获取当前时间,为什么会出现不一样的结果?下面是具体分析

二、oracle时间类型

  • DATE类型:精度为秒,不存储时区信息
  • TIMESTAMP类型:精度为毫秒,不存储时区信息
  • TIMESTAMP WITH TIME ZONE类型:精度为秒,存储时区信息

三、sysdate和systimestamp

  • sysdate类型为DATE,不存储时区信息! 获取当前数据库的系统时区时间,场景中是EST时区
  • systimestamp:类型为TIMESTAMP WITH TIME ZONE,存储时区信息

四、问题解决

1.endtimestamp的类型

首先看下数据库中该字段的类型,是TIMESTAMP(6)类型,精度为秒,不存储时区

2.endtimestamp是怎么插入的

插入时候使用的是joda.time.DateTime类,直接new了一个插入,即获取当前时间,这个类默认插入的是UTC时区!

3.为什么endtimestamp < sysdate会出现问题

endtimestamp存储的是UTC时区时间,sysdate获取的是EST时区时间,存在5个小时时差,因此这里的比较逻辑是错误的

4.为什么endtimestamp < systimestamp没有问题

endtimestamp是TIMESTAMP类型,systimestamp是TIMESTAMP WITH TIME ZONE类型 TIMESTAMP和TIMESTAMP WITH TIME ZONE比较时,会默认TIMESTAMP是UTC时区,进行比较。endtimestamp存储的刚好是UTC时区时间,因此没有问题

五、总结

解决方案的话,修正为endtimestamp < systimestamp是可行的。最终解决方案是删除了这个查询条件,在业务场景中这个条件没有实际意义。