从日期转换为纪元-Oracle

Posted

技术标签:

【中文标题】从日期转换为纪元-Oracle【英文标题】:Convert from date to epoch-Oracle 【发布时间】:2016-06-27 13:24:39 【问题描述】:

我需要将 TextBox 中的日期从日期转换为纪元时间,以便将其插入 Oracle DB。

我设法从纪元转换为日期,如下所示,但找不到另一种方法。

SelectCommand="SELECT ID,
            COMPANY,
            FIRST_NAME,
            LAST_NAME,
            ID_NUMBER,
            (SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')
            +(TRAINING_DATE/60/60/24), 'MM/DD/YYYY') FROM dual) AS TRAINING_DATE,
            (SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')
            +(TRAINING_VALABILITY/60/60/24),'MM/DD/YYYY') FROM dual) AS TRAINING_VALABILITY
    FROM CONTRACTORS
    ORDER BY COMPANY"

【问题讨论】:

您确定要(或应该)在 Oracle 数据库中存储一个纪元时间吗?为什么不存储实际日期?让您的应用程序在需要时将其转换为纪元时间。 不要写(SELECT TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')+(TRAINING_DATE/60/60/24), 'MM/DD/YYYY') FROM dual) AS TRAINING_DATE,简单写TO_CHAR(TO_DATE('01-JAN-1970','DD/MM/YYYY')+(TRAINING_DATE/60/60/24), 'MM/DD/YYYY') AS TRAINING_DATE 注意您当地的时区。 Unix 纪元是 1970-01-01 00:00:00 UTC! 奇怪的是,尽管故意使用了错误的格式掩码,但您的作品代码! :TO_DATE('01-JAN-1970','DD/MM/YYYY')。但是,编写文字日期的最简洁方式是 ANSI 格式:DATE '1970-01-01' 您不能按原样添加 2个日期,但可以减去它们。 【参考方案1】:

从该值中减去 DATE '1970-01-01' 将得到天数(以及小数小时/分钟/秒)的差异,然后您可以乘以 24*60*60

(date_value - DATE '1970-01-01')*24*60*60

更新

通常,纪元时间从1970-01-01T00:00:00 UTC 开始测量。如果您的日期不是 UTC,那么您需要转换时区。

例如,如果您的日期的时区为Europe/Berlin

( CAST(
    FROM_TZ(
      CAST( date_value AS TIMESTAMP ),     -- Cast to timestamp
      'Europe/Berlin'                      -- Convert to expected Time Zone
    )
    AT TIME ZONE 'UTC'                     -- Convert Time Zone to UTC
    AS DATE                                -- Cast back to DATE data type
  )
  - DATE '1970-01-01'
)*24*60*60

db<>fiddle

【讨论】:

这是使用上述方法的示例:select (TO_DATE('02-01-2018', 'MM-DD-YYYY') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60 from dual;【参考方案2】:
UpdateCommand="UPDATE CONTRACTORS
                                           SET COMPANY=:COMPANY,
                                               FIRST_NAME=:FIRST_NAME,
                                               LAST_NAME=:LAST_NAME,
                                               ID_NUMBER=:ID_NUMBER,
                                               TRAINING_DATE=(TO_DATE(:TRAINING_DATE, 'MM-DD-YYYY HH24:MI:SS') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60,
                                               TRAINING_VALABILITY=(TO_DATE(:TRAINING_VALABILITY, 'MM-DD-YY`enter code here`YY HH24:MI:SS') - TO_DATE('01-JAN-1970','DD/MM/YYYY'))*24*60*60
                                           WHERE (ID=:ID)"

【讨论】:

【参考方案3】:

无论输入日期当地时间是否在夏令时 (DST) 期间,我都使用此解决方案。

SELECT Round((Cast(Sys_extract_utc( Cast( your_date_field AS TIMESTAMP )) AS DATE) - To_date('1970-01-01','YYYY-MM-DD HH24MISS')) *24*60*60) AS epoch FROM dual;

-- 'your_date_field'   
-- '20210112' -> 1610427600    (no DST)
-- '20210512' -> 1620792000    (DST)

【讨论】:

以上是关于从日期转换为纪元-Oracle的主要内容,如果未能解决你的问题,请参考以下文章

oracle 将 unix 纪元时间转换为日期

从字符串转换为日期时间时获取常规日期时间格式而不是纪元时间?

将日期从人类可读格式转换为纪元失败

PostgreSQL:如何从 Unix 纪元转换为日期?

在 MS Access SQL 查询中从普通日期转换为 unix 纪元日期

从纪元到日期时间的转换不正确