将时间戳从一个时区转换为另一个时区

Converting Timestamp from one timezone to another

    A Table named TRADES has the following structure and Data:

    CREATE TABLE trades (
        trade_id                NUMBER,
        trade_execution_tmstmp  TIMESTAMP(6),
        time_zone_name          VARCHAR2 (30 BYTE),
        last_trade_marker       TIMESTAMP(6)
);

trade_id -- Unique ID for every trade

trade_execution_tmstmp -- 交易在美国东部标准时间执行的时间 time_zone_name -- 交易的本地时区 last_trade_marker -- 特定日期最后一笔交易的 EST 时间

要求是这样的: 我必须开发一个程序,在另一个 table next_day_trades.

中插入次日交易

如果程序是 1 月 2 日的 运行(在这种情况下),那么第二天只有 1 笔交易,trade_id = 4。所以,next_day_trades table 会有 1 条记录。

决定次日交易的逻辑如下: trade_execution_tmstmp 在美国东部时间。它必须转换为本地时间戳以查看交易在本地市场实际执行的时间。在这种情况下,Australia/Sydney 对于所有行业。 last_trade_marker 是该市场最后一笔交易的时间。

下面是table中第3条和第4条记录的解释。

交易 3 在“1/2/2015 1:00:00.000000 PM”(美国东部时间)执行。 它相当于 Australia/Sydney 时间将是 '1/3/2015 4:00:00.000000 AM' 1 月 2 日的最后一个商标是 '1/3/2015 2:00:00.000000 AM' 如果交易在 12:00 - 02:00 上午(最后交易标记)之间执行,则它将是次日交易。 因此,交易 3 不是次日交易。

交易 4 在“1/2/2015 10:00:00.000000 AM”(美国东部时间)执行。 它相当于 Australia/Sydney 时间将是 '1/3/2015 1:00:00.000000 AM' 1 月 2 日的最后一个商标是 '1/3/2015 2:00:00.000000 AM' 如果交易在 12:00 - 02:00 上午(最后交易标记)之间执行,则它将是次日交易。 因此,交易 4 是次日交易。

注意:次日交易必须仅包含在存储过程执行日。这就是为什么只有交易 4 被插入 next_day_trades table 而不是交易 2,如果 Proc 在 1 月 2 日 运行

请帮我提出一个 SELECT 插入查询。

您可以分两步将您的美国东部标准时间转换为声明的时区;首先通过 from_tz() 声明原始值所在的时区,然后使用 at time zone 转换运算符。

您还需要将最后一个交易标记转换为带时区的时间戳,并且因为您还需要捕获当天的开始(对于您的 00:00-02:00 范围),您需要在应用 from_tz() 之前截断它 - 这使它成为一个日期。

select trade_id, trade_execution_tmstmp, time_zone_name, last_trade_marker,
  from_tz(trade_execution_tmstmp, 'EST') at time zone time_zone_name
    as trade_execution_local_tmstmp,
  from_tz(cast(trunc(last_trade_marker) as timestamp), time_zone_name)
    as last_trade_marker_start,
  from_tz(last_trade_marker, time_zone_name) as last_trade_marker_end
from trades;

随着会话的改变,值的格式略有不同:

alter session set NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
alter session set NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZR';

得到:

  TRADE_ID TRADE_EXECUTION_TMSTM TIME_ZONE_NAME   LAST_TRADE_MARKER     TRADE_EXECUTION_LOCAL_TMSTMP         LAST_TRADE_MARKER_START              LAST_TRADE_MARKER_END              
---------- --------------------- ---------------- --------------------- ------------------------------------ ------------------------------------ ------------------------------------
         1 2015-01-01 13:00:00   Australia/Sydney 2015-01-02 02:00:00   2015-01-02 05:00:00 AUSTRALIA/SYDNEY 2015-01-02 00:00:00 AUSTRALIA/SYDNEY 2015-01-02 02:00:00 AUSTRALIA/SYDNEY
         2 2015-01-01 10:00:00   Australia/Sydney 2015-01-02 02:00:00   2015-01-02 02:00:00 AUSTRALIA/SYDNEY 2015-01-02 00:00:00 AUSTRALIA/SYDNEY 2015-01-02 02:00:00 AUSTRALIA/SYDNEY
         3 2015-01-02 13:00:00   Australia/Sydney 2015-01-03 02:00:00   2015-01-03 05:00:00 AUSTRALIA/SYDNEY 2015-01-03 00:00:00 AUSTRALIA/SYDNEY 2015-01-03 02:00:00 AUSTRALIA/SYDNEY
         4 2015-01-02 10:00:00   Australia/Sydney 2015-01-03 02:00:00   2015-01-03 02:00:00 AUSTRALIA/SYDNEY 2015-01-03 00:00:00 AUSTRALIA/SYDNEY 2015-01-03 02:00:00 AUSTRALIA/SYDNEY

您可以根据我理解的规则比较这些调整后的列值来决定它是否应该是次日交易:

select trade_id, trade_execution_tmstmp, time_zone_name, last_trade_marker,
  case when from_tz(trade_execution_tmstmp, 'EST') at time zone time_zone_name
     between from_tz(cast(trunc(last_trade_marker) as timestamp), time_zone_name)
       and from_tz(last_trade_marker, time_zone_name)
     then 'Yes' else 'No' end as next_day_trade
from trades;

  TRADE_ID TRADE_EXECUTION_TMSTM TIME_ZONE_NAME   LAST_TRADE_MARKER     NEXT_DAY_TRADE
---------- --------------------- ---------------- --------------------- --------------
         1 2015-01-01 13:00:00   Australia/Sydney 2015-01-02 02:00:00   No            
         2 2015-01-01 10:00:00   Australia/Sydney 2015-01-02 02:00:00   Yes           
         3 2015-01-02 13:00:00   Australia/Sydney 2015-01-03 02:00:00   No            
         4 2015-01-02 10:00:00   Australia/Sydney 2015-01-03 02:00:00   Yes           

'Between' 在这里可能不是正确的选择;取决于恰好在 02:00:00.0 的交易是否算作第二天。您可能需要相当于

trade_execution_local_tmstmp >= last_trade_marker_start
and trade_execution_local_tmstmp < last_trade_marker_end

无论哪种方式,您都可以使用相同的条件来决定将哪些行复制到单独的 table。