类别:

转换函数日期和时间函数

TO_TIMESTAMP / TO_TIMESTAMP_*

将输入表达式转换为相应的时间戳:

  • TO_TIMESTAMP_LTZ(包含本地时区的时间戳)

  • TO_TIMESTAMP_NTZ(不包含时区的时间戳)

  • TO_TIMESTAMP_TZ(包含时区的时间戳)

备注

根据 TIMESTAMP_TYPE_MAPPING 会话参数,TO_TIMESTAMP 映射到其他某个时间戳函数。参数默认值为 TIMESTAMP_NTZ,因此 TO_TIMESTAMP 默认映射到 TO_TIMESTAMP_NTZ。

另请参阅:

TRY_TO_TIMESTAMP / TRY_TO_TIMESTAMP_*

AS_TIMESTAMP_*IS_TIMESTAMP_*

TO_DATE、DATETO_TIME、TIME

语法

timestampFunction ( <numeric_expr> [ , <scale> ] )

timestampFunction ( <date_expr> )

timestampFunction ( <timestamp_expr> )

timestampFunction ( <string_expr> [ , <format> ] )

timestampFunction ( '<integer>' )

timestampFunction ( <variant_expr> )
Copy

其中:

timestampFunction ::=
    TO_TIMESTAMP | TO_TIMESTAMP_LTZ | TO_TIMESTAMP_NTZ | TO_TIMESTAMP_TZ
Copy

实参

必填:

其中之一:

numeric_expr

自 Unix 纪元时间 (1970-01-01 00:00:00 UTC) 开始以来的秒数(如果小数位数 = 0 或不存在)或几分之一秒(例如毫秒或纳秒)。如果输入非整数小数表达式,则继承结果的小数位数。

date_expr

要转换为时间戳的日期。

timestamp_expr

要转换为其他时间戳的时间戳(例如,将 TIMESTAMP_LTZ 转换为 TIMESTAMP_NTZ)。

string_expr

要从中提取时间戳的字符串,例如 '2019-01-31 01:02:03.004'

'integer'

计算结果为包含整数的字符串的表达式,例如 '15000000'。根据字符串的大小,它可以解释为秒、毫秒、微秒或纳秒。有关详细信息,请参阅 使用说明

variant_expr

类型 VARIANT 的表达式。VARIANT 必须包含以下内容之一:

  • 要从中提取时间戳的字符串。

  • 时间戳。

  • 一个整数,表示秒、毫秒、微秒或纳秒数。

  • 一个字符串,包含表示秒数、毫秒数、微秒数或纳秒数的整数。

虽然 TO_TIMESTAMP 接受一个 DATE 值,但它不接受 VARIANT 内的 DATE。

可选:

format

格式说明符(仅适用于 string_expr)。有关更多信息,请参阅 转换函数中的日期和时间格式

默认值为 TIMESTAMP_INPUT_FORMAT 参数的当前值(默认为 AUTO)。

scale

小数位数说明符(仅适用于 numeric_expr)。如果已指定,则定义所提供数字的小数位数。例如:

  • 对于秒,小数位数 = 0

  • 对于毫秒,小数位数 = 3

  • 对于微秒,小数位数 = 6

  • 对于纳秒,小数位数 = 9

默认:0

返回

返回值的数据类型是 TIMESTAMP 数据类型。默认情况下,数据类型为 TIMESTAMP_NTZ。您可以设置会话参数 TIMESTAMP_TYPE_MAPPING,从而对此进行更改。

如果输入为 NULL,则结果是 NULL。

使用说明

  • 此系列函数返回时间戳值,具体如下:

    • 对于 string_expr:由给定字符串表示的时间戳。如果字符串没有时间组件,则使用午夜。

    • 对于 date_expr:根据特定时间戳映射 (NTZ/LTZ/TZ) 语义使用表示给定日期午夜的时间戳。

    • 对于 timestamp_expr:可能与源时间戳映射不同的时间戳。

    • 对于 numeric_expr:表示用户提供的秒数(或几分之一秒)的时间戳。UTC 时间始终用于构建结果。

    • 对于 variant_expr

      • 如果 VARIANT 包含 JSON null 值,则结果为 NULL。

      • 如果 VARIANT 包含与结果类型相同的时间戳值,则此值按原样保留。

      • 如果 VARIANT 包含不同类型的时间戳值,则以与 timestamp_expr 相同的方式完成转换。

      • 如果 VARIANT 包含字符串,则将执行从字符串值的转换(使用自动格式)。

      • 如果 VARIANT 包含数字,则将执行从 numeric_expr 的转换。

        备注

        当 INTEGER 值直接转换为 TIMESTAMP_NTZ 时,该整数被视为自 Linux 纪元时间开始以来的秒数,并且不考虑本地时区。但是,如果 INTEGER 值存储在 VARIANT 值内,例如如下所示,则转换是间接的,并且受本地时区的影响,即使最终结果是 TIMESTAMP_NTZ:

        SELECT TO_TIMESTAMP(31000000);
        SELECT TO_TIMESTAMP(PARSE_JSON(31000000));
        SELECT PARSE_JSON(31000000)::TIMESTAMP_NTZ;
        
        Copy

        第一个查询返回的时间戳与第二和第三个查询返回的时间不同。

        要独立于本地时区进行转换,请在表达式中添加显式转换为整数,如下所示:

        SELECT TO_TIMESTAMP(31000000);
        SELECT TO_TIMESTAMP(PARSE_JSON(31000000)::INT);
        SELECT PARSE_JSON(31000000)::INT::TIMESTAMP_NTZ;
        
        Copy

        所有三个查询返回的时间戳相同。无论是类型转换为 TIMESTAMP_NTZ 还是调用函数 TO_TIMESTAMP_NTZ,这都适用。当在将 TIMESTAMP_TYPE_MAPPING参数设置为 TIMESTAMP_NTZ 的情况下调用 TO_TIMESTAMP 时,它也适用。

        有关输出的示例,请参阅本主题末尾的示例。

    • 如果无法进行转换,则会返回错误。

  • 对于带有时区的时间戳,TIMEZONE 参数的设置会影响返回值。返回的时间戳位于会话的时区中。

  • 输出中时间戳的显示格式由与函数对应的时间戳输出格式决定 (TIMESTAMP_OUTPUT_FORMATTIMESTAMP_LTZ_OUTPUT_FORMATTIMESTAMP_NTZ_OUTPUT_FORMATTIMESTAMP_TZ_OUTPUT_FORMAT)。

  • 如果输入参数的格式是包含整数的字符串:

    • 将字符串转换为整数后,该整数被视为自 Unix 纪元时间 (1970-01-01 00:00:00.000000000 UTC) 开始后的秒数、毫秒数、微秒数或纳秒数。

      • 如果整数小于 31536000000(一年中的毫秒数),则该值被视为秒数。

      • 如果该值大于或等于 31536000000 且小于 31536000000000,则该值被视为毫秒数。

      • 如果该值大于或等于 31536000000000 且小于 31536000000000000,则该值被视为微秒数。

      • 如果该值大于或等于 31536000000000000,则该值被视为纳秒数。

    • 如果评估多行(例如,如果输入内容是包含多行的表的列名),则每个值都将单独得到检查,以确定该值表示的是秒数、毫秒数、微秒数还是纳秒数。

  • 使用 TO_TIMESTAMP_NTZ 或 TRY_TO_TIMESTAMP_NTZ 函数,转换带有时区信息的时间戳时,时区信息会丢失。如果将时间戳转换回带有时区信息的时间戳(例如,通过使用 TO_TIMESTAMP_TZ 函数),则时区信息不可恢复。

示例

此示例显示 TO_TIMESTAMP_TZ 创建了一个包含会话中时区的时间戳,但 TO_TIMESTAMP_NTZ 中的值不包含时区:

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';
Copy
SELECT TO_TIMESTAMP_TZ('2024-04-05 01:02:03');
Copy
+----------------------------------------+
| TO_TIMESTAMP_TZ('2024-04-05 01:02:03') |
|----------------------------------------|
| 2024-04-05 01:02:03.000 -0700          |
+----------------------------------------+
SELECT TO_TIMESTAMP_NTZ('2024-04-05 01:02:03');
Copy
+-----------------------------------------+
| TO_TIMESTAMP_NTZ('2024-04-05 01:02:03') |
|-----------------------------------------|
| 2024-04-05 01:02:03.000                 |
+-----------------------------------------+

以下示例显示了不同的格式如何影响模糊日期的解析。假设 TIMESTAMP_TZ_OUTPUT_FORMAT 未设置,因此使用 TIMESTAMP_OUTPUT_FORMAT 并将其设置为默认值 (YYYY-MM-DD HH24:MI:SS.FF3 TZHTZM)。

此示例显示了输入格式为 ``mm/dd/yyyy hh24:mi:ss``(月/日/年)时的结果:

SELECT TO_TIMESTAMP_TZ('04/05/2024 01:02:03', 'mm/dd/yyyy hh24:mi:ss');
Copy
+-----------------------------------------------------------------+
| TO_TIMESTAMP_TZ('04/05/2024 01:02:03', 'MM/DD/YYYY HH24:MI:SS') |
|-----------------------------------------------------------------|
| 2024-04-05 01:02:03.000 -0700                                   |
+-----------------------------------------------------------------+

此示例显示了输入格式为 ``dd/mm/yyyy hh24:mi:ss``(日/月/年)时的结果:

SELECT TO_TIMESTAMP_TZ('04/05/2024 01:02:03', 'dd/mm/yyyy hh24:mi:ss');
Copy
+-----------------------------------------------------------------+
| TO_TIMESTAMP_TZ('04/05/2024 01:02:03', 'DD/MM/YYYY HH24:MI:SS') |
|-----------------------------------------------------------------|
| 2024-05-04 01:02:03.000 -0700                                   |
+-----------------------------------------------------------------+

此示例展示了如何使用表示从 1970 年 1 月 1 日午夜(Unix 纪元开始)开始大约 40 年的数字输入。未指定小数位数,因此使用默认小数位数 ``0``(秒)。

ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF9 TZH:TZM';
Copy
SELECT TO_TIMESTAMP_NTZ(40 * 365.25 * 86400);
Copy
+---------------------------------------+
| TO_TIMESTAMP_NTZ(40 * 365.25 * 86400) |
|---------------------------------------|
| 2010-01-01 00:00:00.000               |
+---------------------------------------+

此示例与前面的示例类似,但通过指定小数位数值 3 来提供以毫秒为单位的值:

SELECT TO_TIMESTAMP_NTZ(40 * 365.25 * 86400 * 1000 + 456, 3);
Copy
+-------------------------------------------------------+
| TO_TIMESTAMP_NTZ(40 * 365.25 * 86400 * 1000 + 456, 3) |
|-------------------------------------------------------|
| 2010-01-01 00:00:00.456                               |
+-------------------------------------------------------+

此示例展示当为相同的数值指定不同的小数位数值时结果会如何变化:

SELECT TO_TIMESTAMP(1000000000, 0) AS "Scale in seconds",
       TO_TIMESTAMP(1000000000, 3) AS "Scale in milliseconds",
       TO_TIMESTAMP(1000000000, 6) AS "Scale in microseconds",
       TO_TIMESTAMP(1000000000, 9) AS "Scale in nanoseconds";
Copy
+-------------------------+-------------------------+-------------------------+-------------------------+
| Scale in seconds        | Scale in milliseconds   | Scale in microseconds   | Scale in nanoseconds    |
|-------------------------+-------------------------+-------------------------+-------------------------|
| 2001-09-09 01:46:40.000 | 1970-01-12 13:46:40.000 | 1970-01-01 00:16:40.000 | 1970-01-01 00:00:01.000 |
+-------------------------+-------------------------+-------------------------+-------------------------+

此示例展示当输入为包含整型的字符串时,该函数如何根据值的大小确定要使用的单位(秒、毫秒、微秒或纳秒)。

使用包含不同范围内的整数的字符串创建并加载表:

CREATE OR REPLACE TABLE demo1 (
  description VARCHAR,
  value VARCHAR -- string rather than bigint
);

INSERT INTO demo1 (description, value) VALUES
  ('Seconds',      '31536000'),
  ('Milliseconds', '31536000000'),
  ('Microseconds', '31536000000000'),
  ('Nanoseconds',  '31536000000000000');
Copy

将字符串传递给函数:

SELECT description,
       value,
       TO_TIMESTAMP(value),
       TO_DATE(value)
  FROM demo1
  ORDER BY value;
Copy
+--------------+-------------------+-------------------------+----------------+
| DESCRIPTION  | VALUE             | TO_TIMESTAMP(VALUE)     | TO_DATE(VALUE) |
|--------------+-------------------+-------------------------+----------------|
| Seconds      | 31536000          | 1971-01-01 00:00:00.000 | 1971-01-01     |
| Milliseconds | 31536000000       | 1971-01-01 00:00:00.000 | 1971-01-01     |
| Microseconds | 31536000000000    | 1971-01-01 00:00:00.000 | 1971-01-01     |
| Nanoseconds  | 31536000000000000 | 1971-01-01 00:00:00.000 | 1971-01-01     |
+--------------+-------------------+-------------------------+----------------+

以下示例将值的类型转换为 TIMESTAMP_NTZ。该示例展示了使用整数和使用包含整数的变体之间的行为差异:

SELECT 0::TIMESTAMP_NTZ, PARSE_JSON(0)::TIMESTAMP_NTZ, PARSE_JSON(0)::INT::TIMESTAMP_NTZ;
Copy
+-------------------------+------------------------------+-----------------------------------+
| 0::TIMESTAMP_NTZ        | PARSE_JSON(0)::TIMESTAMP_NTZ | PARSE_JSON(0)::INT::TIMESTAMP_NTZ |
|-------------------------+------------------------------+-----------------------------------|
| 1970-01-01 00:00:00.000 | 1969-12-31 16:00:00.000      | 1970-01-01 00:00:00.000           |
+-------------------------+------------------------------+-----------------------------------+

返回的时间戳与第一列和第三列中的整数和转换为整数的变体匹配,但返回的时间戳与第二列中未转换为整数的变体不同。有关更多信息,请参阅 使用说明

调用 TO_TIMESTAMP_NTZ 函数时,同样的行为也适用:

SELECT TO_TIMESTAMP_NTZ(0), TO_TIMESTAMP_NTZ(PARSE_JSON(0)), TO_TIMESTAMP_NTZ(PARSE_JSON(0)::INT);
Copy
+-------------------------+---------------------------------+--------------------------------------+
| TO_TIMESTAMP_NTZ(0)     | TO_TIMESTAMP_NTZ(PARSE_JSON(0)) | TO_TIMESTAMP_NTZ(PARSE_JSON(0)::INT) |
|-------------------------+---------------------------------+--------------------------------------|
| 1970-01-01 00:00:00.000 | 1969-12-31 16:00:00.000         | 1970-01-01 00:00:00.000              |
+-------------------------+---------------------------------+--------------------------------------+
语言: 中文