Spanner 在 GoogleSQL 和 Cloud SQL for PostgreSQL 中提供日期和时间戳函数。某些函数(例如 TIMESTAMP
)依赖于时区,接受可选的时区参数。如果函数中未提供时区参数,Spanner 数据库会默认使用 America/Los_Angeles
时区。
使用 Spanner 时,您可以更改数据库的默认时区以自定义此行为。
限制
- 您只能更改没有任何表的空数据库的时区。
- 在语句中提供时区参数会为该语句替换数据库的默认时区。
- REST 和 RPC API 中的所有时间戳都必须使用世界协调时间 (UTC),并以大写的
Z
结尾。 - 查询结果中的时间戳始终以世界协调时间 (UTC) 显示,并附加
Z
。不会执行显示时区转换。
所需的角色
如需获得设置数据库默认时区所需的权限,请让您的管理员为您授予数据库的 Cloud Spanner Database Admin (roles/spanner.databaseAdmin
) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
此预定义角色包含设置数据库默认时区所需的权限。如需查看所需的确切权限,请展开所需权限部分:
所需权限
您需要具备以下权限才能设置数据库默认时区:
-
设置数据库默认时区:
spanner.databases.getDdl, spanner.databases.updateDdl
设置默认时区
如需更改数据库默认时区,请运行以下语句:
GoogleSQL
ALTER DATABASE DATABASE-NAME SET OPTIONS (default_time_zone = 'TIME-ZONE-NAME');
替换以下内容:
- DATABASE-NAME:数据库的名称。 例如
my-database
。 - TIME-ZONE-NAME:要设置的数据库默认时区的名称。必须是 IANA 时区数据库中的有效条目。例如
Etc/UTC
。
PostgreSQL
ALTER DATABASE DATABASE-NAME SET spanner.default_time_zone = 'TIME-ZONE-NAME';
替换以下内容:
- DATABASE-NAME:数据库的名称。 例如
my-database
。 - TIME-ZONE-NAME:要设置的数据库默认时区的名称。必须是 IANA 时区数据库中的有效条目。例如
Etc/UTC
。
示例
以下示例查询展示了如何使用默认时区选项。
未自定义默认时区
如果未在数据库架构中明确设置 default_time_zone 选项,则 default_time_zone 的值为 null,Spanner 会将 America/Los_Angeles
用作默认时区。在以下示例中,America/Los_Angeles
的时间戳偏移量为 UTC-8。
语句:
SELECT TIMESTAMP("2072-12-25 15:30:00") AS timestamp_str;
输出:
/*----------------------*
| timestamp_str |
+----------------------+
| 2072-12-25T23:30:00Z |
*----------------------*/
语句:
SELECT EXTRACT(HOUR FROM TIMESTAMP("2072-12-25 15:30:00")) AS hour;
输出:
/*------*
| hour |
+------+
| 23 |
*------*/
语句:
SELECT TIMESTAMP_TRUNC(TIMESTAMP "2072-12-25 15:30:00", DAY) AS date_str;
输出:
/*----------------------*
| date_str |
+----------------------+
| 2072-12-25T08:00:00Z |
*----------------------*/
默认时区选项设置为 Etc/UTC
以下示例展示了当默认时区选项设置为 Etc/UTC
时,相同语句的行为方式。
语句:
SELECT TIMESTAMP("2072-12-25 15:30:00") AS timestamp_str;
输出:
/*----------------------*
| timestamp_str |
+----------------------+
| 2072-12-25T15:30:00Z |
*----------------------*/
语句:
SELECT EXTRACT(HOUR FROM TIMESTAMP("2072-12-25 15:30:00")) AS hour;
输出:
/*------*
| hour |
+------+
| 15 |
*------*/
语句:
SELECT TIMESTAMP_TRUNC(TIMESTAMP "2072-12-25 15:30:00+00", DAY) AS date_str;
输出:
/*----------------------*
| date_str |
+----------------------+
| 2072-12-25T00:00:00Z |
*----------------------*/
默认时区被函数参数替换
如果函数或字符串字面量包含已定义的时区参数,则不会应用数据库的默认时区。
语句:
SELECT FORMAT_TIMESTAMP("%c", TIMESTAMP "2050-12-25 15:30:55+00", "Australia/Sydney")
AS formatted;
输出:
/*--------------------------*
| formatted |
+--------------------------+
| Mon Dec 26 02:30:55 2050 |
*--------------------------*/
语句:
SELECT TIMESTAMP("2072-12-25 15:30:00+11:00") AS timestamp_str;
输出:
/*----------------------*
| timestamp_str |
+----------------------+
| 2072-12-25T04:30:00Z |
*----------------------*/