设置数据库默认时区

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 语句

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 语句

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 |
 *----------------------*/