Как я могу преобразовать TIMESTAMP_NTZ, который я знаю в UTC, в TIMESTAMP_TZ в Snowflake SQL? - PullRequest
0 голосов
/ 24 октября 2019

У меня есть столбец типа TIMESTAMP_NTZ, и он содержит метку времени, которая, как я знаю, находится в часовом поясе UTC. В основном я хочу преобразовать в TIMESTAMP_TZ, потому что у меня есть другие столбцы, которые TIMESTAMP_TZ, и я хочу иметь возможность выполнять операции, включающие оба.

Я пытался сгенерировать TIMESTAMP_TZ в следующемспособы:

SELECT 
   '2019-10-24 12:07:24.000'::timestamp_ntz as orig -- a literal timestamp_ntz 
   ,convert_timezone('UTC', 'UTC', orig) -- the 3-args version of convert_timezone will always return a TIMESTAMP_NTZ
   ,convert_timezone('UTC', orig) -- the 2-args assumes that orig timezones is session's current timezone 
;

Просто чтобы прояснить, я хочу преобразовать 2019-10-24 12:07:24.000 в 2019-10-24 12:07:24.000 +0000

Есть ли какая-либо функция или оператор в Snowflake, которая позволяет мне сказать, обрабатывать это TIMESTAMP_NTZкак TIMESTAMP_TZ в часовом поясе X?

Ответы [ 5 ]

1 голос
/ 24 октября 2019

Вы должны иметь возможность просто добавить суффикс «Z» к концу исходного TIMESTAMP_NTZ, а затем преобразовать его в TIMESTAMP_TZ, как показано ниже:

-- Set timezone to something which isn't UTC 
alter session set TIMEZONE = 'America/Los_Angeles';
-- Make sure the timestamp TZ output format is as you'd expect
alter session set TIMESTAMP_TZ_OUTPUT_FORMAT = "YYYY-MM-DD HH24:MI:SS.FF3 TZHTZM";

select 
       '2019-10-24 12:07:24.567'::timestamp_ntz as orig, -- Outputs "2019-10-24 12:07:24.567000000"
       (orig::varchar||'Z')::timestamp_tz timestamp_with_tz --Outputs "2019-10-24 12:07:24.567 +0000"
;
1 голос
/ 24 октября 2019

Это работает, если вы знаете местный часовой пояс вашей учетной записи, пользователя или сеанса. Для меня это 'America / New_York':

SELECT current_timestamp::timestamp_ntz as orig, 
       convert_timezone('UTC',convert_timezone('UTC','America/New_York',orig)::timestamp_tz);

Кроме того, если это однократное преобразование, вы можете выполнить:

ALTER SESSION SET TIMEZONE = 'UTC'

Это временно отобразит значения в формате UTCи вы можете преобразовать их в _tz с помощью:

SELECT convert_timezone('UTC', orig)
1 голос
/ 24 октября 2019

Существует два уродливых хака, которые вы можете использовать

  • TIMESTAMP_TZ_FROM_PARTS : создать новый TIMESTAMP_TZ, используя все компоненты из источника TIMESTAMP_NTZ и предоставить часовой пояс какпоследний параметр. Это очень многословно. Смотрите пример ниже.
  • TO_TIMESTAMP_TZ и CONCAT : Сериализация TIMESTAMP_NTZ как строки / VARCHAR, добавление строки часового пояса в конце и повторный анализ всего какTIMESTAMP_TZ.
select 
       '2019-10-24 12:07:24.567'::timestamp_ntz as orig
       ,TIMESTAMP_TZ_FROM_PARTS( year(orig), month(orig),day(orig), hour(orig), minute(orig), second(orig) , date_part(nanosecond, orig), 'UTC' ) 
       ,TO_TIMESTAMP_TZ(orig::varchar || ' +0000')
;

--
2019-10-24 12:07:24.567        -- TIMESTAMP_NTZ (UTC)
2019-10-24 12:07:24.567 +0000  -- TIMESTAMP_TZ  (UTC)
2019-10-24 12:07:24.567 +0000  -- TIMESTAMP_TZ  (UTC)
0 голосов
/ 25 октября 2019

Я бы предложил сначала установить часовой пояс сеанса на UTC.

ALTER SESSION SET TIMEZONE = 'UTC';

Если вы не можете этого сделать и не знаете, что такое часовой пояс сеанса, выможет вычислить это как часть вашего запроса:

SELECT
    DATEDIFF(minute, CONVERT_TIMEZONE('UTC', CURRENT_TIMESTAMP)::timestamp_ntz, CURRENT_TIMESTAMP) AS utc_offset,
    '2019-10-24 12:07:24.567'::timestamp_ntz AS orig,
    CONVERT_TIMEZONE('UTC', DATEADD(minute, utc_offset, orig)) as tz_time;

Это позволяет избежать любых манипуляций со строками (которых я настоятельно рекомендую избегать).

0 голосов
/ 24 октября 2019

Как насчет конвертации в местный часовой пояс и использования convert_timezone для получения часового пояса

SELECT '2019-10-24 12:07:24.000'::timestamp_ntz::timestamp_ltz as orig ,convert_timezone('UTC', orig); 0/p= 2019-10-24 19:07:24.000 +0000

...