

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# 日期时间类型
<a name="r_Datetime_types"></a>

**Topics**
+ [存储和范围](#r_Datetime_types-storage-and-ranges)
+ [DATE](#r_Datetime_types-date)
+ [TIME](#r_Datetime_types-time)
+ [TIMETZ](#r_Datetime_types-timetz)
+ [TIMESTAMP](#r_Datetime_types-timestamp)
+ [TIMESTAMPTZ](#r_Datetime_types-timestamptz)
+ [日期时间类型的示例](r_Examples_with_datetime_types.md)
+ [日期、时间和时间戳文本](r_Date_and_time_literals.md)
+ [间隔数据类型和文字](r_interval_data_types.md)

日期时间数据类型包括 DATE、TIME、TIMETZ、TIMESTAMP 和 TIMESTAMPTZ。

## 存储和范围
<a name="r_Datetime_types-storage-and-ranges"></a>

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Datetime_types.html)

## DATE
<a name="r_Datetime_types-date"></a>

使用 DATE 数据类型存储没有时间戳的简单日历日期。

## TIME
<a name="r_Datetime_types-time"></a>

TIME 是 TIME WITHOUT TIME ZONE 的别名。

使用 TIME 数据类型存储一天中的时间。

TIME 列存储小数秒的精度最高达到 6 位的值。

预设情况下，用户表和 Amazon Redshift 系统表中，TIME 值均为协调世界时 (UTC)。

## TIMETZ
<a name="r_Datetime_types-timetz"></a>

TIMETZ 是 TIME WITH TIME ZONE 的别名。

使用 TIMETZ 数据类型来存储带有时区的一天中的时间。

TIMETZ 列存储小数秒的精度最高达到 6 位的值。

预设情况下，用户表和 Amazon Redshift 系统表中的 TIME 值为 (UTC)。

## TIMESTAMP
<a name="r_Datetime_types-timestamp"></a>

TIMESTAMP 是 TIMESTAMP WITHOUT TIME ZONE 的别名。

使用 TIMESTAMP 数据类型存储包含日期和当日时间的完整时间戳值。

TIMESTAMP 列存储小数秒的精度最高达到 6 位的值。

如果将日期插入到 TIMESTAMP 列中，或插入具有部分时间戳值的日期，则值将隐式转换为完整时间戳值。此完整时间戳值具有缺少的小时、分钟和秒的默认值 (00)。输入字符串中的时区值被忽略。

预设情况下，用户表和 Amazon Redshift 系统表中的 TIMESTAMP 值为 (UTC)。

## TIMESTAMPTZ
<a name="r_Datetime_types-timestamptz"></a>

TIMESTAMPTZ 是 TIMESTAMP WITH TIME ZONE 的别名。

使用 TIMESTAMPTZ 数据类型输入包含日期、当日时间和时区的完整时间戳值。当输入值包含一个时区时，Amazon Redshift 使用时区将值转化为协 UTC 并存储 UTC 值。

要查看支持的时区名称的列表，请执行以下命令。

```
select pg_timezone_names();
```

 要查看支持的时区缩写的列表，请执行以下命令。

```
select pg_timezone_abbrevs();
```

您还可以在 [IANA 时区数据库](https://www.iana.org/time-zones)中找到有关时区的当前信息。

下表提供了时区格式的示例。


| 格式 | 示例 | 
| --- | --- | 
|  dd mon hh:mi:ss yyyy tz  |  17 Dec 07:37:16 1997 PST   | 
|  mm/dd/yyyy hh:mi:ss.ss tz  |  12/17/1997 07:37:16.00 PST  | 
|  mm/dd/yyyy hh:mi:ss.ss tz  |  12/17/1997 07:37:16.00 US/Pacific  | 
|  yyyy-mm-dd hh:mi:ss\$1/-tz  |  1997-12-17 07:37:16-08   | 
| dd.mm.yyyy hh:mi:ss tz |  17.12.1997 07:37:16.00 PST  | 

TIMESTAMPTZ 列存储小数秒的精度最高达到 6 位的值。

如果将日期插入到 TIMESTAMPTZ 列中，或插入具有部分时间戳的日期，则值将隐式转换为完整时间戳值。此完整时间戳值具有缺少的小时、分钟和秒的默认值 (00)。

TIMESTAMPTZ 值为用户表中的 UTC。

# 日期时间类型的示例
<a name="r_Examples_with_datetime_types"></a>

下面，您可以找到处理 Amazon Redshift 支持的日期时间类型的示例。

## 日期示例
<a name="r_Examples_with_datetime_types-date-examples"></a>

以下示例插入具有不同格式的日期并显示输出。

```
create table datetable (start_date date, end_date date);
```

```
insert into datetable values ('2008-06-01','2008-12-31');

insert into datetable values ('Jun 1,2008','20081231');
```

```
select * from datetable order by 1;

start_date |  end_date
-----------------------
2008-06-01 | 2008-12-31
2008-06-01 | 2008-12-31
```

如果您将时间戳值插入 DATE 列，时间部分会被忽略，只会加载日期。

## 时间示例
<a name="r_Examples_with_datetime_types-time-examples"></a>

以下示例插入具有不同格式的 TIME 和 TIMETZ 值并显示输出。

```
create table timetable (start_time time, end_time timetz);
```

```
insert into timetable values ('19:11:19','20:41:19 UTC');
insert into timetable values ('191119', '204119 UTC');
```

```
select * from timetable order by 1;
start_time |  end_time
------------------------
 19:11:19  | 20:41:19+00
 19:11:19  | 20:41:19+00
```

## 时间戳示例
<a name="r_Examples_with_datetime_types-timestamp-examples"></a>

如果您将日期插入到 TIMESTAMP 或 TIMESTAMPTZ 列中，时间将默认为午夜。例如，如果您插入文本 `20081231`，存储的值为 `2008-12-31 00:00:00`。

如要更改当前会话的时区，请使用 [SET](r_SET.md) 命令设置 [timezone](r_timezone_config.md) 配置参数。

下面的示例插入不同格式的时间戳并显示生成的表。

```
create table tstamp(timeofday timestamp, timeofdaytz timestamptz);

insert into tstamp values('Jun 1,2008  09:59:59', 'Jun 1,2008 09:59:59 EST' );
insert into tstamp values('Dec 31,2008 18:20','Dec 31,2008 18:20');
insert into tstamp values('Jun 1,2008  09:59:59 EST', 'Jun 1,2008 09:59:59');

SELECT * FROM tstamp;

+---------------------+------------------------+
|      timeofday      |      timeofdaytz       |
+---------------------+------------------------+
| 2008-06-01 09:59:59 | 2008-06-01 14:59:59+00 |
| 2008-12-31 18:20:00 | 2008-12-31 18:20:00+00 |
| 2008-06-01 09:59:59 | 2008-06-01 09:59:59+00 |
+---------------------+------------------------+
```

# 日期、时间和时间戳文本
<a name="r_Date_and_time_literals"></a>

以下是用于处理 Amazon Redshift 支持的日期、时间和时间戳文本的规则。

## 日期
<a name="r_Date_and_time_literals-dates"></a>

下列输入日期是您可加载到 Amazon Redshift 表中的 DATE 数据类型的文本日期值的所有有效示例。默认 `MDY DateStyle` 模式被认为是有效的。此模式意味着在字符串中，月份值将位于日期值之前，如 `1999-01-08` 和 `01/02/00`。

**注意**  
当您将日期或时间戳文本加载到表中时，这些文本必须用引号括起来。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## Times
<a name="r_Date_and_time_literals-times"></a>

下列输入时间是您可加载到 Amazon Redshift 表中的 TIME 和 TIMETZ 数据类型的文本时间值的所有有效示例。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## 时间戳
<a name="r_Date_and_time_literals-timestamps"></a>

下列输入时间戳是您可加载到 Amazon Redshift 表中的 TIMESTAMP 和 TIMESTAMPTZ 数据类型的文本时间值的所有有效示例。所有有效的日期文本可与下列时间文本组合。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

## 特殊日期时间值
<a name="r_Date_and_time_literals-special-datetime-values"></a>

下列特殊值可用作日期时间文本和日期函数的参数。它们需要单引号，并在查询处理期间转换为常规时间戳值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_Date_and_time_literals.html)

以下示例演示 `now` 和 `today` 如何与 DATEADD 函数结合使用。

```
select dateadd(day,1,'today');

date_add
---------------------
2009-11-17 00:00:00
(1 row)

select dateadd(day,1,'now');

date_add
----------------------------
2009-11-17 10:45:32.021394
(1 row)
```

# 间隔数据类型和文字
<a name="r_interval_data_types"></a>

您可以使用间隔数据类型以 `seconds`、`minutes`、`hours`、`days`、`months`、和 `years` 等为单位存储时间段。间隔数据类型和文字可用于日期时间计算，例如在日期和时间戳中添加间隔、对间隔求和以及从日期或时间戳中减去间隔。间隔文字可用作表中间隔数据类型列的输入值。

## 间隔数据类型的语法
<a name="r_interval_data_types-syntax"></a>

指定间隔数据类型以存储以年和月为单位的持续时间：

```
INTERVAL year_to_month_qualifier
```

指定间隔数据类型以存储以天、小时、分钟和秒为单位的持续时间：

```
INTERVAL day_to_second_qualifier [ (fractional_precision) ]
```

## 间隔文字的语法
<a name="r_interval_data_types-syntax-literal"></a>

指定间隔文字以定义以年和月为单位的持续时间：

```
INTERVAL quoted-string year_to_month_qualifier
```

指定间隔文字以定义以天、小时、分钟和秒为单位的持续时间：

```
INTERVAL quoted-string day_to_second_qualifier [ (fractional_precision) ]
```

## 参数
<a name="r_interval_data_types-arguments"></a>

 *引用字符串*   
指定正数值或负数值，以指定数量和日期时间单位作为输入字符串。如果*引用字符串*仅包含数字，Amazon Redshift 将根据 *year\$1to\$1month\$1qualifier* 或 *day\$1to\$1second\$1qualifier* 确定单位。例如，`'23' MONTH` 表示 `1 year 11 months`、`'-2' DAY` 表示 `-2 days 0 hours 0 minutes 0.0 seconds`，`'1-2' MONTH` 表示 `1 year 2 months`、`'13 day 1 hour 1 minute 1.123 seconds' SECOND` 表示 `13 days 1 hour 1 minute 1.123 seconds`。有关间隔输出格式的更多信息，请参阅[间隔样式](#r_interval_data_types-interval-styles)。

 *year\$1to\$1month\$1qualifier*   
指定间隔的范围。如果您使用限定词并创建时间单位小于限定词的间隔，Amazon Redshift 会截断并丢弃间隔中较小的部分。*year\$1to\$1month\$1qualifier* 的有效值为：  
+ `YEAR`
+ `MONTH`
+ `YEAR TO MONTH`

 *day\$1to\$1second\$1qualifier*   
指定间隔的范围。如果您使用限定词并创建时间单位小于限定词的间隔，Amazon Redshift 会截断并丢弃间隔中较小的部分。*day\$1to\$1second\$1qualifier* 的有效值为：  
+ `DAY`
+ `HOUR`
+ `MINUTE`
+ `SECOND`
+ `DAY TO HOUR`
+ `DAY TO MINUTE`
+ `DAY TO SECOND`
+ `HOUR TO MINUTE`
+ `HOUR TO SECOND`
+ `MINUTE TO SECOND`
INTERVAL 文字的输出会被截断为指定的最小 INTERVAL 分量。例如，在使用 MINUTE 限定词时，Amazon Redshift 会丢弃小于 MINUTE 的时间单位。  

```
select INTERVAL '1 day 1 hour 1 minute 1.123 seconds' MINUTE
```
结果值被截断为 `'1 day 01:01:00'`。

 *fractional\$1precision*   
可选参数，用于指定间隔中允许的小数位数。仅在间隔包含 SECOND 时，才应指定 *fractional\$1precision* 参数。例如，`SECOND(3)` 创建的间隔仅允许三个小数位，例如 1.234 秒。最大小数位数为六位。

会话配置 `interval_forbid_composite_literals` 确定在同时指定 YEAR TO MONTH 和 DAY TO SECOND 部分的间隔时是否返回错误。有关更多信息，请参阅 [interval\$1forbid\$1composite\$1literals](r_interval_forbid_composite_literals.md)。

## 间隔算术
<a name="r_interval_data_types-arithmetic"></a>

您可以将间隔值与其他日期时间值一起使用来执行算术运算。下表介绍了可用的运算以及每种运算产生的数据类型。

**注意**  
 能同时产生 `date` 和 `timestamp` 结果的运算是以等式中涉及的最小时间单位为基础的。例如，在将 `interval` 添加 `date` 时，如果是 YEAR TO MONTH 间隔，则结果为 `date`；如果是 DAY TO SECOND 间隔，则结果为时间戳。

第一操作数为 `interval` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

第一操作数为 `date` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

第一操作数为 `timestamp` 的运算会对给定的第二操作数产生以下结果：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_interval_data_types.html)

## 间隔样式
<a name="r_interval_data_types-interval-styles"></a>

您可以使用 SQL [SET](r_SET.md) 命令更改间隔值的输出显示格式。在 SQL 中使用间隔数据类型时，将其转换为文本可以查看预期的间隔风格，例如 `YEAR TO MONTH::text`。用于设置 `IntervalStyle` 值的可用值包括：
+ `postgres` – 遵循 PostgreSQL 风格。这是默认值。
+ `postgres_verbose` – 遵循 PostgreSQL 的详细风格。
+ `sql_standard` – 遵循 SQL 标准间隔文字风格。

以下命令将间隔风格设置为 `sql_standard`。

```
SET IntervalStyle to 'sql_standard';
```

**postgres 输出格式**

以下是 `postgres` 间隔风格的输出格式。每个数值都可以是负数。

```
'<numeric> <unit> [, <numeric> <unit> ...]'
```

```
select INTERVAL '1-2' YEAR TO MONTH::text 

varchar
---------------
1 year 2 mons
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text

varchar
------------------
1 day 02:03:04.5678
```

**postgres\$1verbose 输出格式**

postgres\$1verbose 语法与 postgres 类似，但是 postgres\$1verbose 输出还包含时间单位。

```
'[@] <numeric> <unit> [, <numeric> <unit> ...] [direction]'
```

```
select INTERVAL '1-2' YEAR TO MONTH::text 

varchar
-----------------
@ 1 year 2 mons
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text

varchar
---------------------------
@ 1 day 2 hours 3 mins 4.56 secs
```

**sql\$1standard 输出格式**

年至月间隔值的格式如下所示。在间隔之前指定负数表示间隔为负值，适用于整个间隔。

```
'[-]yy-mm'
```

日至秒值间隔的格式如下所示。

```
'[-]dd hh:mm:ss.ffffff'
```

```
SELECT INTERVAL '1-2' YEAR TO MONTH::text 
  
varchar   
-------
1-2
```

```
select INTERVAL '1 2:3:4.5678' DAY TO SECOND::text 

varchar
---------------
1 2:03:04.5678
```

## 间隔数据类型示例
<a name="r_interval_data_types-examples"></a>

以下示例演示如何将 INTERVAL 数据类型与表结合使用。

```
create table sample_intervals (y2m interval month, h2m interval hour to minute);
insert into sample_intervals values (interval '20' month, interval '2 days 1:1:1.123456' day to second);
select y2m::text, h2m::text from sample_intervals;


      y2m      |       h2m      
---------------+-----------------
 1 year 8 mons | 2 days 01:01:00
```

```
update sample_intervals set y2m = interval '2' year where y2m = interval '1-8' year to month;
select * from sample_intervals;

   y2m   |       h2m       
---------+-----------------
 2 years | 2 days 01:01:00
```

```
delete from sample_intervals where h2m = interval '2 1:1:0' day to second;
select * from sample_intervals;

 y2m | h2m 
-----+-----
```

## 间隔文字示例
<a name="r_interval_data_types_literals-examples"></a>

以下示例在间隔风格设置为 `postgres` 的情况下运行。

以下示例演示如何创建间隔为 1 年的 INTERVAL 文字。

```
select INTERVAL '1' YEAR 

intervaly2m
---------------
1 years 0 mons
```

如果您指定的*引用字符串*超过限定词，则剩余的时间单位将从间隔处截断。在以下示例中，13 个月的间隔变为 1 年零 1 个月，但由于使用 YEAR 限定词，剩余的 1 个月被排除在外。

```
select INTERVAL '13 months' YEAR

intervaly2m
---------------
1 years 0 mons
```

如果您使用的限定词小于间隔字符串，则会包括排除的单位。

```
select INTERVAL '13 months' MONTH

intervaly2m
---------------
1 years 1 mons
```

在间隔中指定精度会将小数位数截断为指定的精度。

```
select INTERVAL '1.234567' SECOND (3)

intervald2s
--------------------------------
0 days 0 hours 0 mins 1.235 secs
```

如果您未指定精度，Amazon Redshift 将使用最大精度 6。

```
select INTERVAL '1.23456789' SECOND

intervald2s
-----------------------------------
0 days 0 hours 0 mins 1.234567 secs
```

以下示例演示如何创建范围间隔。

```
select INTERVAL '2:2' MINUTE TO SECOND

intervald2s
------------------------------
0 days 0 hours 2 mins 2.0 secs
```

限定词决定了您要指定的单位。例如，尽管以下示例使用与前一个示例相同的“2:2”*引用字符串*，但 Amazon Redshift 仍会识别出它由于限定词而使用了不同的时间单位。

```
select INTERVAL '2:2' HOUR TO MINUTE

intervald2s
------------------------------
0 days 2 hours 2 mins 0.0 secs
```

还支持每个单位的缩写和复数。例如，`5s`、`5 second`、和 `5 seconds` 是等效间隔。支持的单位为年、月、小时、分钟和秒。

```
select INTERVAL '5s' SECOND

intervald2s
------------------------------
0 days 0 hours 0 mins 5.0 secs
```

```
select INTERVAL '5 HOURS' HOUR

intervald2s
------------------------------
0 days 5 hours 0 mins 0.0 secs
```

```
select INTERVAL '5 h' HOUR

intervald2s
------------------------------
0 days 5 hours 0 mins 0.0 secs
```

# 不带限定词语法的间隔文字示例
<a name="r_interval_literals"></a>

**注意**  
以下示例演示如何使用不带 `YEAR TO MONTH` 或 `DAY TO SECOND` 限定词的间隔文字。有关将推荐的间隔文字与限定词一起使用的信息，请参阅[间隔数据类型和文字](r_interval_data_types.md)。

使用间隔文本标识特定时间段（如 `12 hours` 或 `6 months`）。您可在涉及日期时间表达式的条件和计算中使用这些间隔文本。

 间隔文字用 INTERVAL 关键字与数量和支持的日期部分的组合来表示；例如 `INTERVAL '7 days'` 或 `INTERVAL '59 minutes'`。您可以将许多数量和单位连接在一起以形成更精确的间隔；例如：`INTERVAL '7 days, 3 hours, 59 minutes'`。还支持每个单位的缩写和复数；例如：`5 s`、`5 second` 和 `5 seconds` 是等效的间隔。

如果您未指定日期部分，则间隔值表示秒。您可指定数量值作为小数（例如：`0.5 days`）。

以下示例显示了具有不同间隔值的一系列计算。

以下选项向指定日期添加 1 秒。

```
select caldate + interval '1 second' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 00:00:01
(1 row)
```

以下选项向指定日期添加 1 分钟。

```
select caldate + interval '1 minute' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 00:01:00
(1 row)
```

以下选项向指定日期添加 3 小时 35 分钟。

```
select caldate + interval '3 hours, 35 minutes' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 03:35:00
(1 row)
```

以下选项向指定日期添加 52 周。

```
select caldate + interval '52 weeks' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2009-12-30 00:00:00
(1 row)
```

以下选项向指定日期添加 1 周、1 小时、1 分钟和 1 秒：

```
select caldate + interval '1w, 1h, 1m, 1s' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2009-01-07 01:01:01
(1 row)
```

以下选项向指定日期添加 12 小时（半天）。

```
select caldate + interval '0.5 days' as dateplus from date
where caldate='12-31-2008';
dateplus
---------------------
2008-12-31 12:00:00
(1 row)
```

以下计算将从 2023 年 2 月 15 日减去 4 个月，结果为 2022 年 10 月 15 日。

```
select date '2023-02-15' - interval '4 months';

?column?
---------------------
2022-10-15 00:00:00
```

以下计算将从 2023 年 3 月 31 日减去 4 个月，结果为 2022 年 11 月 30 日。计算时会考虑一个月中的天数。

```
select date '2023-03-31' - interval '4 months';

?column?
---------------------
2022-11-30 00:00:00
```