From 9d7e7ccc081534edd896e331ec998c491e2d32a0 Mon Sep 17 00:00:00 2001 From: chenkuangwei Date: Tue, 27 Jan 2026 17:47:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20postgresql=5Fand=5Fedb/pos?= =?UTF-8?q?tgresql=E6=97=B6=E9=97=B4=E7=B1=BB=E5=9E=8B.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postgresql_and_edb/postgresql时间类型.md | 88 ++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 postgresql_and_edb/postgresql时间类型.md diff --git a/postgresql_and_edb/postgresql时间类型.md b/postgresql_and_edb/postgresql时间类型.md new file mode 100644 index 0000000..17f02bc --- /dev/null +++ b/postgresql_and_edb/postgresql时间类型.md @@ -0,0 +1,88 @@ +PostgreSQL 提供了丰富且强大的时间日期数据类型。为了方便查阅,我将其整理成了下方的表格,涵盖了存储空间、范围、精度及常见用途。 + +### PostgreSQL 时间类型概览 + +| 类型名称 | 别名/常用写法 | 存储空间 | 描述 | 格式示例 | 建议使用场景 | +| --- | --- | --- | --- | --- | --- | +| **`timestamp [without time zone]`** | `timestamp` | 8 bytes | 日期和时间 (**不含**时区) | `2024-05-20 14:30:00` | 记录因果发生且与地理位置无关的时间 (如未来的具体的日历事件)。 | +| **`timestamp with time zone`** | **`timestamptz`** | 8 bytes | 日期和时间 (**含**时区) | `2024-05-20 14:30:00+08` | **最推荐**。记录跨国业务、日志、交易时间。存储时转为 UTC,查询时转为客户端时区。 | +| **`date`** | - | 4 bytes | 仅日期 (无时间) | `2024-05-20` | 生日、节假日、预定日期。 | +| **`time [without time zone]`** | `time` | 8 bytes | 仅时间 (无日期) | `14:30:00` | 闹钟设置、每日固定任务时间。 | +| **`time with time zone`** | `timetz` | 12 bytes | 仅时间 (含时区) | `14:30:00+08` | **不推荐使用** (SQL 标准仅为向后兼容保留)。 | +| **`interval`** | - | 16 bytes | 时间间隔 (时长) | `1 year 2 mons`
+ +
`3 days 04:05:06` | 计算两个时间点之间的差值,或做时间的加减运算。 | + +--- + +### 核心区别详解:`timestamp` vs `timestamptz` + +这是 PostgreSQL 中最容易混淆但也最重要的概念。 + +#### 1. `timestamp` (无时区) + +* **特性**:你存什么,它就原封不动地记什么。数据库**不关心**时区。 +* **问题**:如果你在东京存入 `09:00`,在伦敦读出来还是 `09:00`。对于跨国应用,这会导致时间错乱。 + +#### 2. `timestamptz` (含时区) + +* **特性**:它是**时区感知**的。 +* **存储机制**:当数据存入时,PostgreSQL 会根据当前的 `TimeZone` 配置,将时间转换为 **UTC** (世界标准时间) 进行存储。 +* **读取机制**:当查询数据时,PostgreSQL 会将存储的 UTC 时间转换为当前客户端连接的 `TimeZone` 显示。 +* **误区**:它**不会**存储你原本的时区名字(如 "Asia/Shanghai"),它只存储 UTC 值。 + +> **最佳实践**:在绝大多数应用场景下,建议默认使用 **`timestamptz`**,以避免时区转换带来的麻烦。 + +--- + +### 常用操作速查 + +以下是一些高频使用的 SQL 示例: + +**1. 获取当前时间** + +```sql +SELECT now(); -- 返回当前的 timestamptz (最常用) +SELECT current_date; -- 返回当前日期 +SELECT current_timestamp; -- 等同于 now() + +``` + +**2. 类型转换 (Casting)** + +```sql +-- 字符串转时间 +SELECT '2024-01-01'::date; +SELECT '2024-01-01 10:00:00'::timestamp; + +-- Unix 时间戳 (秒) 转时间 +SELECT to_timestamp(1716180000); + +``` + +**3. 时间计算 (使用 Interval)** + +```sql +-- 当前时间加 7 天 +SELECT now() + interval '7 days'; + +-- 当前时间减 1 小时 +SELECT now() - interval '1 hour'; + +-- 计算两个日期的间隔 +SELECT age(timestamp '2024-12-31', timestamp '2024-01-01'); + +``` + +**4. 截断时间 (Date Trunc)** +非常适合做报表统计(按月、按天统计)。 + +```sql +-- 将时间截断到"月" (即使是5月20日,也会变成5月1日 00:00) +SELECT date_trunc('month', now()); + +``` + + + +如果您正在处理具体的业务场景(例如:“我想计算用户的留存时间” 或 “我需要处理不同时区的订单数据”),您可以告诉我,我可以为您编写具体的 **SQL 查询语句**示例。 \ No newline at end of file