用 PostgreSQL age() 函数计算年龄与任意两个时间点之间的时间跨度

发布时间:2026/10/8 11:24:58
用 PostgreSQL age() 函数计算年龄与任意两个时间点之间的时间跨度 文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载在 PostgreSQL 中age()函数是计算时间跨度的利器传入单个时间戳即可得到从该时刻到现在的年龄如自 Y2K 以来过去了多久传入两个时间戳则可求出任意两点之间以年、月、天为单位的时间差如某个人的寿命。本文以 postgres/determining-the-age-of-things.md 为主线结合本仓库中关于 interval、timestamp 转换与时序函数的多篇 TIL完整讲解age()的两种调用形式、返回值语义、输入构造方式与实战场景。age() 返回的是什么符号化的 intervalage()函数的返回值类型是 PostgreSQL 的interval。但它的特殊之处在于普通的时间减法如timestamp1 - timestamp2通常只以天 小数秒的形式给出结果而age()会输出一种**符号化symbolic**的 interval——即把时间差拆解为X years Y mons Z days这种更接近人类阅读习惯的表示这也正是本仓库 postgres/determining-the-age-of-things.md 示例中输出16 years 4 mons 12 days的原因。关于interval数据类型的更多定义方式可参考本仓库 postgres/different-ways-to-define-an-interval.md既可以用interval 3 days关键字加字符串也可以3 days::interval强转还可以通过make_interval(days 3)函数构造。理解interval的表示能力是正确解读age()返回结果的前提。单参数形式age(timestamp) 计算距今时长age()最常用的是单参数形式——传入一个时间戳返回从该时刻到当前时间的跨度。原文档中给出的示例是计算自 Y2K2000 年 1 月 1 日以来已经过去了多久 select age(timestamp 2000-01-01); age ------------------------- 16 years 4 mons 12 days这里timestamp 2000-01-01是 PostgreSQL 的标准时间戳字面量写法类型关键字 字符串常量。age()会以当前日期为基准做减法输出结果是符号化的 interval。在实际查询中当前时间也可以显式指定例如配合本仓库 postgres/timestamp-functions.md 中介绍的now()等价于transaction_timestamp()表示当前事务开始时刻来对比验证-- 结果随当前时刻变化例如 select age(now() - interval 3 days); age ------------------ 3 days需要注意age(timestamp)的单参数形式是按日历方式计算整年整月整天的差值而不是按固定的 24 小时一天来换算这正是它适合表达年龄这类概念的原因。双参数形式age(timestamp1, timestamp2) 计算两个时间点之差当我们需要计算任意两个时间点之间的跨度时使用双参数形式age(timestamp1, timestamp2)返回timestamp1减去timestamp2的结果输出为X years Y mons Z days的形式。原文档以美国歌手 Prince 为例——传入死亡日期和出生日期计算其享年 select age(timestamp April 21, 2016, timestamp June 7, 1958); age -------------------------- 57 years 10 mons 14 days这里两个时间戳都使用了自然语言风格的字符串字面量April 21, 2016PostgreSQL 的字符串解析器能够识别这种表达并自动转换为 timestamp 类型。输出57 years 10 mons 14 days即为其实际寿命。参数顺序与符号含义双参数形式的语义是第一个参数减去第二个参数因此age(2016-04-21, 1958-06-07)得到正值后面的时间在后若两个参数调换顺序结果会变成负数如-57 years -10 mons -14 days这与 PostgreSQL 中时间减法保持一致的符号约定参数既可以是timestamp类型也可以是date类型会按需转换只要保证两个参数的类型可以参与差值运算。输入时间戳的三种构造方式age()的两个参数本质上都需要解析为timestamp或可隐式转换的类型。除原文档展示的字符串字面量写法如timestamp 2000-01-01外还有以下几种常见构造方式。方式一ISO 8601 字符串直接强转本仓库 postgres/convert-a-string-to-a-timestamp.md 指出符合 ISO 8601 格式的字符串可以直接::timestamptz强转 select 2018-10-24::timestamptz; timestamptz ------------------------ 2018-10-24 00:00:00-05这种形式同样可以作为age()的参数 select age(2018-10-24::timestamptz);方式二to_timestamp() 按模板解析任意格式当字符串不是标准 ISO 格式时可以使用to_timestamp(text, format)按格式模板解析 select to_timestamp(2018-10-24, YYYY-MM-DD); to_timestamp ------------------------ 2018-10-24 00:00:00-05第一个参数是待转换的字符串第二个参数描述其格式。该方法对非标准输入如April 21, 2016这类英文日期也能通过Month DD, YYYY模板可靠解析。方式三从列数据直接传入实际业务中最常见的是直接传入表中存储的 timestamp/date 列例如计算用户年龄、合同剩余天数select name, age(birth_date) as current_age from users;此时age(birth_date)直接复用单参数形式以当前日期为基准得出每位用户的年龄配合WHERE条件即可筛选特定年龄段人群。实战场景age() 的典型用法场景一计算记录距今的时长结合本仓库 postgres/timestamp-functions.md 中介绍的时间函数可以灵活地表达距今多久-- 订单创建至今的时间跨度 select order_id, age(created_at) as age_of_order from orders order by created_at desc;场景二过滤指定时间跨度的记录利用age()的返回值与interval比较可以过滤出超过 X 时间的记录。例如找出注册超过 1 年的用户select * from users where age(created_at) interval 1 year;关于interval字面量的多种写法详见 postgres/different-ways-to-define-an-interval.md。场景三以年-月-天形式展示业务时长当需要向用户展示入职 X 年 Y 个月这类人类可读的时长时age()的符号化输出正好符合需求免去手动按天数换算年月的麻烦。注意事项与边界时间基准单参数age(timestamp)以当前日期本地时区为基准结果会随时间推移而变化若需要固定基准请使用双参数形式显式传入两个时间戳。返回值不是纯天数age()输出的是年/月/天符号化结构直接做天数级别的算术比较时建议先将其与interval常量比较或使用EXTRACT(EPOCH FROM interval)转成秒数。时区语义若使用带时区的timestamptz差值计算基于时间点本身若使用无时区的timestamp则按会话时区的日历语义计算。构造输入时建议明确使用带时区类型避免跨时区业务出现偏差参见 postgres/convert-a-string-to-a-timestamp.md 对timestamptz的说明。日期范围辅助当需要同时表达一个时间段而非单一跨度时可参考 postgres/constructing-a-range-of-dates.md 中的daterange()函数它与age()共同构成了 PostgreSQL 处理时间域的两类基本工具。小结age()是 PostgreSQL 中表达年龄和时间跨度最直观的函数age(timestamp)从当前日期算起返回符号化 intervalage(timestamp1, timestamp2)返回两时间点之差第一个减去第二个同样以年-月-天呈现输入支持字符串字面量、ISO 强转、to_timestamp()模板解析以及表列数据等多种来源返回结果可与interval常量比较实现按时间跨度过滤等常见需求。完整示例可继续阅读本仓库的 postgres/determining-the-age-of-things.md该文档也是本仓库 READMEREADME.mdPostgres 分类下列出的经典 TIL 条目。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐实测 Inpaint-web零安装的浏览器图像修复与在线图片超分辨率实测 Inpaint web零安装的浏览器图像修复与在线图片超分辨率 产品图上的供应商水印你还要再开一次 Photoshopinpaint web 是一款图像处理AI 应用前端StarRocks years_diff 函数详解计算两个日期/时间表达式之间的年份差StarRocks years_diff 函数详解计算两个日期/时间表达式之间的年份差 本篇技术指南围绕 StarRocks 的 years_diff 日期时数据库OLAP数据仓库大数据湖仓一体数据分析Bumbler入门教程3分钟学会追踪Rails项目初始化加载进度Bumbler入门教程3分钟学会追踪Rails项目初始化加载进度 Bumbler是一款专为Bundler项目设计的加载进度追踪工具能帮助开发者实时监控Rai开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考