惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Hacker News
The Hacker News
Martin Fowler
Martin Fowler
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
U
Unit 42
F
Full Disclosure
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Recorded Future
Recorded Future
Security Archives - TechRepublic
Security Archives - TechRepublic
阮一峰的网络日志
阮一峰的网络日志
T
Threatpost
P
Privacy International News Feed
GbyAI
GbyAI
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
I
Intezer
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Privacy & Cybersecurity Law Blog
A
Arctic Wolf
博客园 - 聂微东
博客园 - 叶小钗
Cisco Talos Blog
Cisco Talos Blog
H
Help Net Security
S
Schneier on Security
Y
Y Combinator Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Exploit Database - CXSecurity.com
T
Tor Project blog
月光博客
月光博客
NISL@THU
NISL@THU
A
About on SuperTechFans
Spread Privacy
Spread Privacy
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
雷峰网
雷峰网
C
CXSECURITY Database RSS Feed - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 【当耐特】
G
Google Developers Blog
W
WeLiveSecurity
P
Palo Alto Networks Blog
The Last Watchdog
The Last Watchdog
K
Kaspersky official blog
博客园 - 司徒正美
L
LINUX DO - 热门话题
小众软件
小众软件

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
如何使用 Notion 函数计算星座与年龄 - 少数派
2023-05-24 · via 少数派

2023-11-02 修改注:Notion 于近期发布了 Formulas 2.0 版本,对大量函数的语法及输出值进行了修改,因此本文所包含公式的部分语法已不可用。为便于理解,本文保留了最初的公式,但出于避免产生误解的目的,又在不可用的公式后方新增了标注,并在每个小节后方附上了优化后的新公式。如果「太长不看」,读者也可以直接拷贝每个小节最后的新公式进行使用。

用 Excel 公式计算星座与年龄听上去并不是一件困难之事,在搜索引擎上也能找到现成的答案。但是如若使用 Notion 的函数体系来执行这个任务的话,似乎就成为了一种挑战。

我这里 Notion 里有一个数据库,记载了我各路亲朋好友的小孩子们的大名、小名以及生日。为了不错过这些小朋友们的生日,我利用了 Notion 的函数功能来自动计算他们的星座、年龄以及距离下次生日的倒计时,就像这样(数据已脱敏处理):

这些函数公式我也同时用在了其他的一些数据库里,例如在我的「设备清单」中,我可以直观地看到这些设备的服役时长。接下来我就详细说说这里面的实现原理。

本文已经假设你对 Notion 的函数体系有了初步的了解。如果你还不太了解,可以看看少数派作者 Niin 的这篇文章:建立强大的 Notion 数据库,从了解函数开始

星座的计算方式

Excel 里有一个现成的星座计算公式:

=LOOKUP(--TEXT(D2,"mdd"),{101,"摩羯座";120,"水瓶座";219,"双鱼座";321,"白羊座";420,"金牛座";521,"双子座";622,"巨蟹座";723,"狮子座";823,"处女座";923,"天秤座";1024,"天蝎座";1123,"射手座";1222,"摩羯座"})

为了移植到 Notion 中来,我们可以使用 if 这个函数,它其中一种用法是 boolean ? value : value。仿照 Excel 公式的思路,先通过 (month(prop("生日")) + 1) * 100 + date(prop("生日") 这个算式将生日转化为 mdd 格式,然后加入 if 的嵌套判断,就形成了使用 Notion 函数计算星座的方法:

((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 1222) ? "摩羯座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 1123) ? "射手座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 1024) ? "天蝎座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 923) ? "天秤座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 823) ? "处女座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 723) ? "狮子座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 622) ? "巨蟹座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 521) ? "双子座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 420) ? "金牛座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 321) ? "白羊座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 219) ? "双鱼座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 120) ? "水瓶座" : (((month(prop("生日")) + 1) * 100 + date(prop("生日")) >= 101) ? "摩羯座" : ""))))))))))))

/* 注:最新版 Notion 修改了 month(date) 函数,该公式基于旧版本撰写,仅供参考,更新后的公式见本节最下方。 */

2023-11-02 更新:由于 Notion Formulas 2.0 已支持声明变量,且 Notion Formulas 2.0 对 month(date) 函数进行了修改,month(prop("生日")) 转化为 mdd 格式的时候不需要额外 +1 了,经过优化的最新版公式如下:

let(
  x, ((month(prop("生日")) * 100) + date(prop("生日"))),
  (x >= 1222) ? "摩羯座" : ((x >= 1123) ? "射手座" : ((x >= 1024) ? "天蝎座" : ((x >= 923) ? "天秤座" : ((x >= 823) ? "处女座" : ((x >= 723) ? "狮子座" : ((x >= 622) ? "巨蟹座" : ((x >= 521) ? "双子座" : ((x >= 420) ? "金牛座" : ((x >= 321) ? "白羊座" : ((x >= 219) ? "双鱼座" : ((x >= 120) ? "水瓶座" : ((x >= 101) ? "摩羯座" : ""))))))))))))
)

年龄的计算方式

把年龄表述为「y 岁」似乎没有什么难度,但我想把年龄表述成「y 岁 m 个月 d 天」这种格式。用 Excel 实现的话大概是这样:

=DATEDIF(D2,TODAY(),"Y")&" 岁 "&DATEDIF(D2,TODAY(),"YM")&" 个月 "&DATEDIF(D2,TODAY(),"MD")&" 天"

但是用 Notion 函数实现就相对麻烦一些。最简单的方案是仿照上述 Excel 公式的方式,使用 dateBetween 函数分别计算岁数、余月、以及余日,再用 format 将数字转换成字符串,然后使用 concat 函数将多个字符串拼接在一起。

/* 计算年龄 - 年 */
dateBetween(now(), prop("生日"), "years")

/* 计算年龄 - 余月 */
dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")

/* 计算年龄 - 余日 */
dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")

/* 使用 concat 函数进行拼接 */
concat(format(dateBetween(now(), prop("生日"), "years")), " 岁 ", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")

/* 注:最新版 Notion 修改了 concat() 函数,该公式基于旧版本撰写,仅供参考,更新后的公式见本节最下方。 */

这样确实就形成了与 Excel 公式效果完全一致的 Notion 函数,但接下来我又发现一些问题,譬如说它会出现「3 岁 0 个月 0 天」这种情况,不太符合语法的习惯表述。于是我尝试加上零整判断,就像这样:

/* 计算年龄 - 年,如果不为零则展示为「y 年」,如果为零则展示为空 */
(dateBetween(now(), prop("生日"), "years") != 0) ? concat(format(dateBetween(now(), prop("生日"), "years")), " 岁") : ""

/* 计算年龄 - 余月,如果不为零则展示为「m 个月」,如果为零则展示为空 */
(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years") != 0) ? concat((dateBetween(now(), prop("生日"), "years") != 0) ? " " : "", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月") : ""

/* 计算年龄 - 余日,如果不为零则展示为「d 天」,如果为零则展示为空 */
(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days") != 0) ? concat(" ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天") : ""

/* 使用 concat 函数进行拼接 */
concat((dateBetween(now(), prop("生日"), "years") != 0) ? concat(format(dateBetween(now(), prop("生日"), "years")), " 岁") : "", (dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years") != 0) ? concat((dateBetween(now(), prop("生日"), "years") != 0) ? " " : "", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月") : "", (dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days") != 0) ? concat(" ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天") : "")

/* 注:最新版 Notion 修改了 concat() 函数,该公式基于旧版本撰写,仅供参考,更新后的公式见本节最下方。 */

这样这个函数就可以使用了,对于「3 岁 0 个月 0 天」这种情况直接就展示为「3 岁」了。但你以为这就完了吗?对于追求完美的我来说还不够。我接下来尝试把「零」、「整」、「不到一天」这些判断统统加进来,就像这样:

为了实现这个效果,代码需要这样写:先在草稿纸上绘制好流程图,再把基于流程图的 if 嵌套的框架写好,避免弄错。

/* 一种写法 */
y == 0 ? (m == 0 ? (d == 0 ? "A" : "B") : (d == 0 ? "C" : "D")) : (m == 0 ? (d == 0 ? "E" : "F") : (d == 0 ? "G" : "H"))

/* 另一种写法 */
if(y == 0, if(m == 0, if(d == 0, "A", "B"), if(d == 0, "C", "D")), if(m == 0, if(d == 0, "E", "F"), if(d == 0, "G", "H")))

同时把每种文案的格式先预填好(Notion 无法声明变量,只能这样啦):

/* "A" */
"不到一天"

/* "B" */
concat(format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")

/* "C" */
concat(format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月整")

/* "D" */
concat(format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")

/* "E" */
concat(format(dateBetween(now(), prop("生日"), "years")), " 岁整")

/* "F" */
concat(format(dateBetween(now(), prop("生日"), "years")), " 岁零 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")

/* "G" */
concat(format(dateBetween(now(), prop("生日"), "years")), " 岁 ", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月整")

/* "H" */
concat(format(dateBetween(now(), prop("生日"), "years")), " 岁 ", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")

/* 注:最新版 Notion 已支持声明变量,且修改了 concat() 函数,该公式基于旧版本撰写,仅供参考,更新后的公式见本节最下方。 */

再把它们全都代入进去,并在最前面加上一个判断生日是否为空的逻辑 empty(prop("生日")) ? true : false,最后就形成了这样一段函数(是的它就有这么长,但是很好用):

empty(prop("生日")) ? "" : (dateBetween(now(), prop("生日"), "years") == 0 ? ((dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")) == 0 ? ((dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")) == 0 ? "不到一天" : concat(format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")) : ((dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")) == 0 ? concat(format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月整") : concat(format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天"))) : ((dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")) == 0 ? ((dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")) == 0 ? concat(format(dateBetween(now(), prop("生日"), "years")), " 岁整") : concat(format(dateBetween(now(), prop("生日"), "years")), " 岁零 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天")) : ((dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")) == 0 ? concat(format(dateBetween(now(), prop("生日"), "years")), " 岁 ", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月整") : concat(format(dateBetween(now(), prop("生日"), "years")), " 岁 ", format(dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years")), " 个月 ", format(dateBetween(now(), dateAdd(dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), dateBetween(now(), prop("生日"), "months") - 12 * dateBetween(now(), prop("生日"), "years"), "months"), "days")), " 天"))))

2023-11-02 更新:由于 Notion Formulas 2.0 已支持声明变量,且 Notion Formulas 2.0 对 concat() 函数进行了修改,经过优化的最新版公式如下(支持变量以后缩短了很多):

empty(prop("生日")) ? "" : lets(
  y, dateBetween(now(), prop("生日"), "years"), /* 计算年龄 - 年 */
  m, dateBetween(now(), prop("生日"), "months"), /* 计算年龄 - 月 */
  m1, (m - 12 * y), /* 计算年龄 - 余月 */
  d1, dateBetween(now(), dateAdd(dateAdd(prop("生日"), y, "years"), m - 12 * y, "months"), "days"), /* 计算年龄 - 余日 */
  t1, "不到一天",
  t2, (format(d1) + " 天"),
  t3, (format(m - 12 * y) + " 个月整"),
  t4, (format(m - 12 * y) + " 个月 " + format(d1) + " 天"),
  t5, (format(y) + " 岁整"),
  t6, (format(y) + " 岁零 " + format(d1) + " 天"),
  t7, (format(y) + " 岁 " + format(m - 12 * y) + " 个月整"),
  t8, (format(y) + " 岁 " + format(m - 12 * y) + " 个月 " + format(d1) + " 天"),
  y == 0 ? (m1 == 0 ? (d1 == 0 ? t1 : t2) : (d1 == 0 ? t3 : t4)) : (m1 == 0 ? (d1 == 0 ? t5 : t6) : (d1 == 0 ? t7 : t8))
)

距离下次生日的计算方式

最后我们再补上一列,「距离下次生日」的日期倒数。在 Excel 上我们可以这样写:

=IF(D2,DATE(YEAR(D2)+DATEDIF(D2+1,TODAY(),"y")+1,MONTH(D2),DAY(D2))-TODAY(),"")

在 Notion 上,我们需要先计算下一次生日的具体日期:

dateAdd((prop("生日")), (dateBetween(now(), prop("生日"), "years") + 1), "years")

然后再计算距离下次生日的天数,由于 dateBetween 函数计算未来是负数,此处需要变为正数,然后加上 1。再加上生日为空以及生日在当天的判断后,最终函数为:

/* 简化版,不包含生日为空以及生日在当天的判断 */
1 - dateBetween(now(), dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years") + 1, "years"), "days")

/* 完整版,包含生日为空以及生日在当天的判断 */
empty(prop("生日")) ? 0 : ((dateBetween(now(), dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years"), "years"), "days") == 0) ? 0 : (1 - dateBetween(now(), dateAdd(prop("生日"), dateBetween(now(), prop("生日"), "years") + 1, "years"), "days")))

这样我们就可以计算出「距离下次生日」的日期倒数。在 Notion 上可以用这一列来进行排序,它就会动态调整接下来要过生日的小朋友们的次序了。

2023-11-02 更新:由于 Notion Formulas 2.0 已支持声明变量,经过优化的最新版公式如下:

empty(prop("生日")) ? 0 : lets(
  y, dateBetween(now(), prop("生日"), "years"),
  ((dateBetween(now(), dateAdd(prop("生日"), y, "years"), "days") == 0) ? 0 : (1 - dateBetween(now(), dateAdd(prop("生日"), y + 1, "years"), "days")))
)