oracle 将 unix 纪元时间转换为日期
oracle convert unix epoch time to date
上下文是我们的产品中有一个现有的应用程序,它生成 EPOCH 编号并将其发送到现有的 oracle 程序,反之亦然。它在那个过程中使用这样的东西工作
SELECT UTC_TO_DATE (1463533832) FROM DUAL
SELECT date_to_utc(creation_date) FROM mytable
当我尝试这些查询时,它对我也适用于 Oracle 10g 服务器(如果重要的话,还有 oracle sql 开发人员 4.x)。
在现有程序中,要求是将值保存为日期本身(时间部分无关紧要),但是在新要求中,我必须将 unix EPOCH 值转换为日期时间(在 hours/mins/seconds 级别,或者在 oracle 查询中以特定格式(例如 dd-MMM-yyyy hh:mm:ss)更好。奇怪的是,我无法找到有关 UTC_TO_DATE 和 DATE_TO_UTC 函数以及 Google 的任何文档。我查看了关于 Whosebug 的所有不同问题,但其中大部分都是特定于编程语言的,例如 php、java 等
最重要的是,如何在 Oracle 查询中使用这些函数(或任何其他函数)将 EPOCH 转换为该级别的时间?此外,我所指的那些功能可能是自定义的或特定于某处的,因为我没有看到任何文档或对此的引用。
从纪元转换为毫秒(假设纪元是 1970 年 1 月 1 日):
select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 / 1000) * 1322629200000
from dual;
2011 年 11 月 30 日 5:00:00 上午
将该日期转换回毫秒:
select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60 * 1000
from dual;
1322629200000
如果是秒而不是毫秒,只需省略等式的 1000 部分:
select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 ) * 1322629200
from dual;
select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60
from dual;
希望对您有所帮助。
另一种选择是使用间隔类型:
SELECT TO_TIMESTAMP('1970-01-01 00:00:00.0'
,'YYYY-MM-DD HH24:MI:SS.FF'
) + NUMTODSINTERVAL(1493963084212/1000, 'SECOND')
FROM dual;
它的优点是不会被削减毫秒。
这里是 UTC/GMT 和 EST;
GMT select (to_date('1970-01-01 00','yyyy-mm-dd hh24') +
(1519232926891)/1000/60/60/24) from dual;
EST select new_time(to_date('1970-01-01 00','yyyy-mm-dd hh24') +
(1519232926891)/1000/60/60/24, 'GMT', 'EST') from dual;
我想有人会对这个的 Oracle 函数版本感兴趣:
CREATE OR REPLACE FUNCTION unix_to_date(unix_sec NUMBER)
RETURN date
IS
ret_date DATE;
BEGIN
ret_date:=TO_DATE('19700101','YYYYMMDD')+( 1/ 24/ 60/ 60)*unix_sec;
RETURN ret_date;
END;
/
我有一堆需要日期的记录,所以我更新了我的 table 为:
update bobfirst set entered=unix_to_date(1500000000+a);
其中 a 是 1 到 10,000,000 之间的数字。
如果你的纪元时间存储为整数......
并且您希望转换为 Oracle 日期格式。
第一步-->
将您的纪元日期 (1462086000) 添加到标准 01-jan-1970。 86400 是 24 小时内的秒数。
*Select TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 from dual*
**output is 5/1/2016 7:00:00 AM**
第 2 步 --> 将其转换为 CHAR 。这是在应用其他功能之前进行格式化所必需的。
*Select TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss') from dual*
output is 2016-05-01 07:00:00
第 3 步 --> 现在进行时间戳转换
Select to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') from dual
output is 5/1/2016 7:00:00.000000000 AM
第 4 步 --> 现在需要时区,使用 UTC
Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') from dual
output is 5/1/2016 7:00:00.000000000 AM +00:00
第 5 步 --> 如果您需要的时区是 PST
Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') at time zone 'America/Los_Angeles' TZ from dual
output is 5/1/2016 12:00:00.000000000 AM -07:00
第 6 步 --> 格式化 PST 时区时间戳。
Select to_Char(from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') at time zone 'America/Los_Angeles' ,'DD-MON-YYYY HH24:MI:SS') TZ from dual
output is 01-MAY-2016 00:00:00
第 7 步 --> 最后,如果您的列是日期数据类型
Add to_DATE to the whole above Select.
将时间戳转换为纳秒的更短方法。
SELECT (EXTRACT(DAY FROM (
SYSTIMESTAMP --Replace line with desired timestamp --Maximum value: TIMESTAMP '3871-04-29 10:39:59.999999999 UTC'
- TIMESTAMP '1970-01-01 00:00:00 UTC') * 24 * 60) * 60 + EXTRACT(SECOND FROM
SYSTIMESTAMP --Replace line with desired timestamp
)) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为时间戳的方法。
SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS TIMESTAMP FROM dual;
TIMESTAMP
26/08/20 09:33:47,263027000 UTC
不出所料,上述方法的结果不受时区影响。
一种将时间间隔转换为纳秒的较短方法。
SELECT (EXTRACT(DAY FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval --Maximum value: INTERVAL '+694444 10:39:59.999999999' DAY(6) TO SECOND(9) or up to 3871 year
) * 24 * 60) * 60 + EXTRACT(SECOND FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval
))) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为间隔的方法。
SELECT numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS INTERVAL FROM dual;
INTERVAL
+18500 09:33:47.263027
正如预期的那样,毫秒、微米和纳米被转换和还原,尽管 SYSTIMESTAMP 没有纳秒信息。
将 1000000000 替换为 1000,例如,如果您想使用毫秒而不是纳秒。
我试过一些posted的方法,但是大部分都受时区影响或者还原后数据丢失,所以我决定做post这些方法对我有用。
上下文是我们的产品中有一个现有的应用程序,它生成 EPOCH 编号并将其发送到现有的 oracle 程序,反之亦然。它在那个过程中使用这样的东西工作
SELECT UTC_TO_DATE (1463533832) FROM DUAL
SELECT date_to_utc(creation_date) FROM mytable
当我尝试这些查询时,它对我也适用于 Oracle 10g 服务器(如果重要的话,还有 oracle sql 开发人员 4.x)。
在现有程序中,要求是将值保存为日期本身(时间部分无关紧要),但是在新要求中,我必须将 unix EPOCH 值转换为日期时间(在 hours/mins/seconds 级别,或者在 oracle 查询中以特定格式(例如 dd-MMM-yyyy hh:mm:ss)更好。奇怪的是,我无法找到有关 UTC_TO_DATE 和 DATE_TO_UTC 函数以及 Google 的任何文档。我查看了关于 Whosebug 的所有不同问题,但其中大部分都是特定于编程语言的,例如 php、java 等
最重要的是,如何在 Oracle 查询中使用这些函数(或任何其他函数)将 EPOCH 转换为该级别的时间?此外,我所指的那些功能可能是自定义的或特定于某处的,因为我没有看到任何文档或对此的引用。
从纪元转换为毫秒(假设纪元是 1970 年 1 月 1 日):
select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 / 1000) * 1322629200000
from dual;
2011 年 11 月 30 日 5:00:00 上午
将该日期转换回毫秒:
select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60 * 1000
from dual;
1322629200000
如果是秒而不是毫秒,只需省略等式的 1000 部分:
select to_date('19700101', 'YYYYMMDD') + ( 1 / 24 / 60 / 60 ) * 1322629200
from dual;
select (to_date('11/30/2011 05:00:00', 'MM/DD/YYYY HH24:MI:SS') - to_date('19700101', 'YYYYMMDD')) * 24 * 60 * 60
from dual;
希望对您有所帮助。
另一种选择是使用间隔类型:
SELECT TO_TIMESTAMP('1970-01-01 00:00:00.0'
,'YYYY-MM-DD HH24:MI:SS.FF'
) + NUMTODSINTERVAL(1493963084212/1000, 'SECOND')
FROM dual;
它的优点是不会被削减毫秒。
这里是 UTC/GMT 和 EST;
GMT select (to_date('1970-01-01 00','yyyy-mm-dd hh24') +
(1519232926891)/1000/60/60/24) from dual;
EST select new_time(to_date('1970-01-01 00','yyyy-mm-dd hh24') +
(1519232926891)/1000/60/60/24, 'GMT', 'EST') from dual;
我想有人会对这个的 Oracle 函数版本感兴趣:
CREATE OR REPLACE FUNCTION unix_to_date(unix_sec NUMBER)
RETURN date
IS
ret_date DATE;
BEGIN
ret_date:=TO_DATE('19700101','YYYYMMDD')+( 1/ 24/ 60/ 60)*unix_sec;
RETURN ret_date;
END;
/
我有一堆需要日期的记录,所以我更新了我的 table 为:
update bobfirst set entered=unix_to_date(1500000000+a);
其中 a 是 1 到 10,000,000 之间的数字。
如果你的纪元时间存储为整数...... 并且您希望转换为 Oracle 日期格式。
第一步--> 将您的纪元日期 (1462086000) 添加到标准 01-jan-1970。 86400 是 24 小时内的秒数。
*Select TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 from dual*
**output is 5/1/2016 7:00:00 AM**
第 2 步 --> 将其转换为 CHAR 。这是在应用其他功能之前进行格式化所必需的。
*Select TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss') from dual*
output is 2016-05-01 07:00:00
第 3 步 --> 现在进行时间戳转换
Select to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss') from dual
output is 5/1/2016 7:00:00.000000000 AM
第 4 步 --> 现在需要时区,使用 UTC
Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') from dual
output is 5/1/2016 7:00:00.000000000 AM +00:00
第 5 步 --> 如果您需要的时区是 PST
Select from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') at time zone 'America/Los_Angeles' TZ from dual
output is 5/1/2016 12:00:00.000000000 AM -07:00
第 6 步 --> 格式化 PST 时区时间戳。
Select to_Char(from_tz(to_timestamp(TO_CHAR(TO_DATE('01-jan-1970', 'dd-mon-yyyy') + 1462086000/86400 ,'yyyy-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss'),'UTC') at time zone 'America/Los_Angeles' ,'DD-MON-YYYY HH24:MI:SS') TZ from dual
output is 01-MAY-2016 00:00:00
第 7 步 --> 最后,如果您的列是日期数据类型
Add to_DATE to the whole above Select.
将时间戳转换为纳秒的更短方法。
SELECT (EXTRACT(DAY FROM (
SYSTIMESTAMP --Replace line with desired timestamp --Maximum value: TIMESTAMP '3871-04-29 10:39:59.999999999 UTC'
- TIMESTAMP '1970-01-01 00:00:00 UTC') * 24 * 60) * 60 + EXTRACT(SECOND FROM
SYSTIMESTAMP --Replace line with desired timestamp
)) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为时间戳的方法。
SELECT TIMESTAMP '1970-01-01 00:00:00 UTC' + numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS TIMESTAMP FROM dual;
TIMESTAMP
26/08/20 09:33:47,263027000 UTC
不出所料,上述方法的结果不受时区影响。
一种将时间间隔转换为纳秒的较短方法。
SELECT (EXTRACT(DAY FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval --Maximum value: INTERVAL '+694444 10:39:59.999999999' DAY(6) TO SECOND(9) or up to 3871 year
) * 24 * 60) * 60 + EXTRACT(SECOND FROM (
INTERVAL '+18500 09:33:47.263027' DAY(5) TO SECOND --Replace line with desired interval
))) * 1000000000 AS NANOS FROM DUAL;
NANOS
1598434427263027000
一种将纳秒转换为间隔的方法。
SELECT numtodsinterval(
1598434427263027000 --Replace line with desired nanoseconds
/ 1000000000, 'SECOND') AS INTERVAL FROM dual;
INTERVAL
+18500 09:33:47.263027
正如预期的那样,毫秒、微米和纳米被转换和还原,尽管 SYSTIMESTAMP 没有纳秒信息。
将 1000000000 替换为 1000,例如,如果您想使用毫秒而不是纳秒。
我试过一些posted的方法,但是大部分都受时区影响或者还原后数据丢失,所以我决定做post这些方法对我有用。