检查 Oracle 查询中的 expiryDate

checking expiryDate in Oracle query

我有一个 table 包含开始日期,ExpiryDate,我想写一个 oracle 查询来检查到期日期是否大于当前系统日期,然后我想 return 该行,否则 null 将是查询的结果。

我写了这样的东西,

 select Name,Password,StartDate,ExpiryDate from db_name where UserName = 'abc' and status =1 and ExpiryDate >=(SELECT Round((sysdate - to_date('01-JAN-1970','DD-MON-YYYY')) * (86400))*1000 as dt FROM dual);

这里是 table 描述:

 STARTDATE                 NOT NULL NUMBER(20)
 EXPIRYDATE                NOT NULL NUMBER(20)

值:

EXPIRYDATE
----------
1.5880E+12

在执行 select to_char(startdate),to_char(expirydate) 等查询后,我得到

TO_CHAR(STARTDATE)
----------------------------------------
TO_CHAR(EXPIRYDATE)
----------------------------------------
1587909960000
1587996480000

但它在所有情况下都工作正常,但如果到期日期小于(当前时间+6 小时),它会给出 null,谁能告诉我如何解决这个问题?

Unix 纪元时间,嗯?看看这是否有帮助。

将日期格式设置为可识别:

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

示例数据:

SQL> select * From test;

             STARTDATE             EXPIRYDATE
---------------------- ----------------------
         1587909960000          1587996480000

转换为 DATE 值:

SQL> select
  2    date '1970-01-01' + ( 1 / 24 / 60 / 60 / 1000) * startdate  startdt,
  3    date '1970-01-01' + ( 1 / 24 / 60 / 60 / 1000) * expirydate expdt
  4  from test;

STARTDT             EXPDT
------------------- -------------------
26.04.2020 14:06:00 27.04.2020 14:08:00

或者,与 sysdate 一起使用:

SQL> select *
  2  from test
  3  where sysdate between
  4    date '1970-01-01' + ( 1 / 24 / 60 / 60 / 1000) * startdate and
  5    date '1970-01-01' + ( 1 / 24 / 60 / 60 / 1000) * expirydate;

             STARTDATE             EXPIRYDATE
---------------------- ----------------------
         1587909960000          1587996480000

因为 sysdate 目前是:

SQL> select sysdate from dual;

SYSDATE
-------------------
27.04.2020 12:45:56

在我看来,你的这些日期是 Javascript 风格的时间戳。也就是说,看起来它们是自 UNIX epoch 1970-01-01 00:00:00 UTC 以来的时间(以毫秒为单位)。请注意,它们参考的是 UTC,而不是您当地的时区。你的时区是Asia/Dhaka吗?那是比 UTC 早六小时。

在我看来,您的时间戳也有十秒的精度。你显示的两个能被10000整除

这是将 Javascript 次转换为 Oracle UTC date/time 值的公式

 SELECT TO_DATE('19700101','yyyymmdd') + (1587909960000/86400000) FROM DUAL;

这会在 UTC 时间而不是本地时间 中生成 SYSDATE 样式的值呈现。它产生 2020-04-26 14:06:00

因为你有明显的六小时误差,我猜你当地的时区是Asia/Dhaka,UTC+6。但它也可能是 America/Denver, UTC-6.

和你的时间价值,运行 通过该公式,产生 2020-04-26 14:06:00。这似乎是最近有效的 date/time.

这是一个猜测!如果您正在使用其他人的钱或生活在您的数据库中,请询问编写程序的人。这不是 DBMS 原生的处理方式,因此您应该仔细检查。

公式是怎么回事?

在 Oracle 中,将 1.0 添加到 SYSDATE - 样式值会增加一个日历日。所以我们从 UNIX 纪元 TO_DATE('19700101','yyyymmdd').

的 Oracle 日期开始

然后我们将您的毫秒时间戳值转换为天,除以 86 400 000,最后我们将其添加到纪元日期。

这里有一些关于获取 UTC 当前时间的建议,因此您可以将其与您的时间戳数据进行比较。 How to get UTC value for SYSDATE on Oracle

Unix 纪元时间在 UTC 时区。您可以将当前时间转换为UTC时区,然后减去纪元:

SELECT Name,
       Password,
       StartDate,
       ExpiryDate
FROM   IM_USER_MANAGEMENT
WHERE  UserName = 'abc'
AND    status =1
AND    ExpiryDate >= ( CAST( SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE )
                       - DATE '1970-01-01'
                     )*24*60*60*1000