将 UTC 时间戳(毫秒)插入 Oracle 时间戳列

Posted

技术标签:

【中文标题】将 UTC 时间戳(毫秒)插入 Oracle 时间戳列【英文标题】:Insert UTC timestamp (millis) into Oracle timestamp column 【发布时间】:2016-11-30 14:23:25 【问题描述】:

有没有办法以毫秒为单位直接将值(例如 1480515430991)转换为 Oracle TIMESTAMP(6) 列?就像我在 TO_TIMESTAMP 或 TO_DATE 函数中缺少的某些模式一样?

到目前为止,我能找到的只是一些带有间隔的计算和 to_date('1970-01-01','YYYY-MM-DD') 或其他疯狂的“手动”计算。 p>

谢谢

编辑: 多谢你们。我没有问如何进行转换。我问是否有一种直接(本机,更直接)的方法来实现它并避免对给定输入进行这些计算。我只是一个好奇的人,那里有许多未记录的特性(不排除 Oracle)。我想 NO 是我的答案。

【问题讨论】:

0毫秒是什么意思?那是一天的开始吗?星期?其他日期? 时代。这是自 1970-01-01 以来的毫秒数。 时间戳是小数秒,而不是毫秒。在这里可以找到11g的to_timestamp函数docs.oracle.com/cd/B28359_01/olap.111/b28126/…的文档 @Kousalik 否,默认以秒为单位。 你是对的:没有 Oracle 函数将 Unix 时间作为参数并输出 Oracle 日期或时间戳。唯一的方法是使用手动计算。不知道为什么你认为计算是“疯狂的”——任何可以为你进行转换的函数都会使用相同的计算。也许“疯狂”的是我们都必须重复相同的计算,而不是 Oracle 提供的工具,但这不是计算本身的特征。向甲骨文投诉! 【参考方案1】:

正确的函数,即包括时区考虑和毫秒将是这个(使用文字):

create or replace function epoch2timestamp(epoch number) return timestamp as
begin
return (TIMESTAMP '1970-01-01 00:00:00 UTC' + epoch/1000 * INTERVAL '1' SECOND) AT LOCAL;
end;
/

【讨论】:

【参考方案2】:

这是从纪元获取时间戳的方法。:

select to_timestamp('1970-01-01','yyyy-mm-dd') + ( 1 / 24 / 60 / 60 / 1000) * epoch from dual;

所以在插入时请插入to_timestamp('1970-01-01','yyyy-mm-dd') + ( 1 / 24 / 60 / 60 / 1000) * epoch 而不是纪元。您也可以为此创建函数:

create or replace function epoch2timestamp(epoch number) return timestamp as
begin
return to_timestamp('1970-01-01','yyyy-mm-dd') + ( 1 / 24 / 60 / 60 / 1000) * epoch;
end;
/

然后对函数进行操作。这些不是“疯狂的手工计算”,只是一种合法的转换方式。

【讨论】:

正如我在问题中所说的,这是我自己能想到的。 @Kousalik 这是您问题的答案。这是您需要的直接转换。不投票不会给你更好的答案,但会阻止其他人帮助你。 注意,此函数将返回结果为 UTC 值,而不是您的本地时间。如果需要,您可以考虑时区并进行转换。 你的函数在以下方面是“疯狂的”:创建一个 TIMESTAMP,隐式转换为 DATE,再一次隐式转换为 TIMESTAMP。【参考方案3】:

如果你想表达 unix 时间,从纪元开始的时间,你需要秒,而不是毫秒。见Unixtime

Oracle 的数据类型 TIMESTAMP 以秒为单位,您可以在 Oracle 文档中阅读。 Link zu 11g documentation

日期的年、月和日值,以及时间的小时、分钟和秒值,其中 fractional_seconds_precision 是 SECOND 日期时间字段小数部分的位数。 fractional_seconds_precision 的可接受值为 0 到 9。

回答你的问题:有一个TO_TIMESTAMP 函数。见11g documentation

TO_TIMESTAMP 函数将文本数据转换为 TIMESTAMP 数据类型的值。

你可以这样使用它

TO_TIMESTAMP('2016/11/30 15:53:18', 'YYYY/MM/DD HH:MI:SS')

会得到 '30-NOV-16 15.53.18.000000000 AM'


如果由于某种原因,你真的需要显示秒数,你可以使用非疯狂计算

select (SYSDATE - to_date('1970-01-01', 'yyyy-MM-dd')) * 24 * 60 * 60 from dual;

【讨论】:

只有当您的数据库服务器在 UTC 时区运行时才正确。

以上是关于将 UTC 时间戳(毫秒)插入 Oracle 时间戳列的主要内容,如果未能解决你的问题,请参考以下文章

Python - 给定时间戳UTC和UTC偏移量的时区名称

php获取UTC时间戳

使用 PHP 将时间戳以毫秒为单位插入 Postgres 表

Java 如何获得 Unix 时间戳

JDBC:在 UTC 中插入时间戳

在 Oracle 时间戳列中以 UTC 保存日期