发布日期:2026-10-05 浏览次数:5
算时间差"这个说法包含两件不同的事,先分清才不会白试。
| 你的需求 | 该用什么 |
|---|---|
| 两个日期一共差几天 | ⭐ 直接相减 |
| 差几年几个月几日(例如"工龄 3 年 5 个月") | ⭐ 用 DATEDIF |
⭐⭐ 为什么要分成两种,而不是一个公式搞定:
因为"天数"是有唯一答案的(从 A 到 B 就是那么多天);而"几年几个月"取决于你怎么算月——所以它需要你指定"按什么单位算"。
⭐ 这句话解释了一件事:
DATEDIF 看起来"参数很多",是因为"年月日"本来就不是一个数,而是三个。
这是最简单的一种,也是最快能得出结果的。
⭐ 做法:假设起始日期在 A2、结束日期在 B2,直接写:
代码块
=B2-A2
结果就是两个日期相差的天数。
⭐ 一个很常用的变体:算"还剩几天到期":
代码块
=到期日 - TODAY()
⚠️ 而这里要提醒一件事:相减的前提是"两格都是真正的日期"。 如果它们其实是文本,结果就会不对(见第七节第一个坑)。
需要"分别算年、月、日"时用它。
⭐ 语法是:
代码块
=DATEDIF(起始日期, 结束日期, "单位")
⭐ 而"单位"这一栏有五种填法,这是它的核心:
| 单位 | 得到什么 |
|---|---|
"y" |
完整年数 |
"m" |
完整月数 |
"d" |
完整天数 |
"ym" |
⭐ 不满一年的月数 |
"md" |
⭐ 不满一月的天数 |
⭐⭐ 后两个单位是它真正的价值所在:
"y" 只告诉你"满几年",而 "ym" 告诉你"还多出几个月"——把两者拼起来,才是我们平时说的"3 年 5 个月"。
⚠️ 关于 "md" 我要加一句提醒:
这个单位在边界情况下的结果可能不符合直觉(例如涉及月末时)——所以如果你的场景对天数很敏感,建议手工核对一两例,别直接把它当成"绝对准确"。
把上面的单位组合起来,就是一个很常用的写法。
⭐ 假设入职日期在 A2,想算"到今天几年几个月":
代码块
=DATEDIF(A2, TODAY(), "y") & "年" & DATEDIF(A2, TODAY(), "ym") & "个月"
⭐ 它是怎么拼出来的:
| 部分 | 作用 |
|---|---|
第一个 DATEDIF |
拿到满年数 |
第二个 DATEDIF |
拿到不满一年的月数 |
& |
把数字和"年""个月"这些字拼成一句话 |
结果就会显示成"3年5个月"这种形式。
⭐⭐ 而这里有一个很关键的性质:
TODAY() 会自动取当天的日期——所以这张表每天打开,工龄都是最新的,不需要你手动改。
⭐ 它的实际含义是:
你只需要维护"入职日期"这一列,工龄会自己往前走。
⚠️ 但也正因为这样,它带来一个坑(见第七节的坑 5):
如果你的目的是"留档",那么这份表永远在变。
掌握了两种基本写法之后,这几种都是它的组合。
| 你的需求 | 写法 |
|---|---|
| 还剩几天到期 | =到期日 - TODAY() |
| 一共多少个月(例如合同期) | =DATEDIF(A2, B2, "m") |
| 算年龄 | =DATEDIF(生日, TODAY(), "y") |
| ⭐ 自动标出"已过期" | =IF(B2<TODAY(), "已过期", "还剩" & B2-TODAY() & "天") |
| 算两个日期之间有几个工作日 | ⚠️ 要用另一个函数,不是 DATEDIF |
⭐⭐ 最后一行是一条重要边界:
DATEDIF 算的是"日历差",不是"工作日差"。
⭐ 为什么这两个数在业务上经常不一样:
| 场景 | 日历差 | 工作日差 |
|---|---|---|
| "还有几天到期" | 有意义 | 未必 |
| ⭐ "这个活要几个工作日" | ❌ 会把周末算进去 | 才是你要的 |
⚠️ 所以如果你的需求涉及"工作日",别用 DATEDIF 硬凑——去查一下专门算工作日的函数,否则算出来的数字会把周末和假期都算进去。
⭐ 而第四个"自动标出已过期"值得留意:
它把"算时间差"和"判断"合在了一个公式里——这在做台账、合同管理、证照到期提醒时特别省事:你不需要每天去看,表自己会告诉你哪几行该处理了。
DATEDIF 是"隐藏"的这是很多人第一次用 DATEDIF 就会卡住的地方。
它通常不会出现在函数提示列表或自动补全里——所以你得把公式完整手输进去。
⭐ 由此得到一个很实际的结论:
| 你可能会 | 实际 |
|---|---|
| 在函数列表里找"日期差" | ⚠️ 找不到 |
| 输前几个字母等提示 | ⚠️ 可能没有提示 |
| ⭐ 直接手输完整公式 | ✅ 能用 |
⭐ 所以它常被叫做"隐藏函数":
功能是有效的,只是不在引导里出现——这也是为什么"搜到公式照抄"比"自己在菜单里找"更快。
如果你要把公式往下拉给整列用,这一条很关键。
⭐ 日期通常在同一列、行号往下走——所以引用应该写成:
代码块
=DATEDIF($A2, TODAY(), "y")
⭐⭐ 关键就在那个 $:
| 写法 | 往下填充时会怎样 |
|---|---|
⚠️ DATEDIF(A2, ...) |
列和行都跟着走——在某些布局下会引用到错误的列 |
⭐ DATEDIF($A2, ...) |
列被锁住,行号往下走——这才是你要的 |
⭐ 一句话记法:
列要钉住($A),行要跟着走(2)。
⚠️ 这和"查找重复项"那篇里讲的区域锁定是同一类问题——一个是锁"起始行",一个是锁"列",但根源都是"填充时引用会漂移"。
见《WPS 表格怎么查找重复项》。
时间差这类表有一个共同特点:输入少、输出多——所以它值得一次做对,然后长期用。
| 做法 | 效果 |
|---|---|
| 入职日期只填一次 | ⭐ 工龄自己往前走 |
| ⭐ 公式做成整列(填充一次) | 新增一行也自动算 |
| 加一列"剩余天数" | 可以按它排序 |
| 再加一列"状态"(已过期 / 还剩 N 天) | ⭐ 一眼看出哪几行该动 |
⭐⭐ 这四行合起来,就是一个"台账"该有的样子:
你只维护"输入"(日期),输出(工龄、剩余天数、状态)全部由公式算出来。
⭐ 为什么这一点值得强调:
很多人的做法是"每次要报表了就手动算一遍"——这样既慢,又容易在某个环节算错。 而把它做成公式之后,你要做的事只剩下"看一眼"。
⚠️ 而唯一的例外还是那条:
如果这份表要留档,记得把公式转成数值——否则你会得到一张"每天都在变"的历史记录。
| # | 坑 | 说明 |
|---|---|---|
| 1 | ⭐ 日期其实是文本 | 相减会出错或得负数 |
| 2 | 结束日期早于起始日期 | 结果会不对 |
| 3 | ⭐ 在函数列表里找不到 DATEDIF |
它是"隐藏"的,要手输 |
| 4 | 往下填充时引用漂移 | 用 $A2 锁列 |
| 5 | ⚠️ 留档时工龄还在变 | 因为 TODAY() 每天都变 |
⭐ 坑 1 值得展开,因为它和另一个问题同源:
"日期看起来是日期、其实是文本"这件事,与"数字看起来是数字、其实是文本"是完全同一类问题——症状也一样:公式不报错,但结果不对。
⭐ 怎么判断:真正的日期默认靠右对齐,文本默认靠左;或者把一个日期加 1,看它会不会变成第二天。
⭐⭐ 坑 5 是很多人没想到的:
用了 TODAY() 的表格,是"活的"——它在你要"留档"的时候会变成一个麻烦:
| 场景 | 问题 |
|---|---|
| 要归档"截至某日的工龄" | ⚠️ 明天打开就变了 |
| 要在报告里引用一个固定数字 | ⚠️ 数字和你当时看到的可能不一样 |
⭐ 解法很简单:留档前选中那一列,用"选择性粘贴 → 数值"把公式变成固定数字。
⭐ 一句话:
TODAY() 让表"自动更新",而"留档"要的恰恰是"别变"——两者需要你手动切换一次。
| 做法 | 问题 | 正确做法 |
|---|---|---|
| 用相减算"几年几个月" | 得到的是天数 | ⭐ 要年月就用 DATEDIF |
| 在函数列表里找 DATEDIF | 找不到 | ⭐ 手输完整公式 |
| 引用不锁列就往下填充 | 引用漂移 | 用 $A2 |
| 日期是文本就直接相减 | 结果不对 | 先转成真日期 |
| 留档时保留公式 | 数字会一直变 | ⭐ 选择性粘贴成数值 |
把 "md" 当绝对准确 |
边界情况可能不符直觉 | 抽查一两例 |
只写 "y" 就说"工龄3年半" |
丢了月数 | 加 "ym" 拼出月份 |
| 手改每一行的工龄 | 天天要改 | ⭐ 用 TODAY() 自动走 |
WPS 表格怎么算两个日期的天数差? 直接相减:⭐ =B2-A2,结果就是天数。 要算"还剩几天到期",用 =到期日-TODAY()。
DATEDIF 的公式怎么写? ⭐ =DATEDIF(起始日期, 结束日期, "单位"),单位填 "y" 算年、"m" 算月、"d" 算天。
算工龄该用哪个? 用 DATEDIF 最合适。 ⭐ =DATEDIF(入职日期, TODAY(), "y") 得到满年数,再加 "ym" 就能得到"不满一年的月数",拼起来就是"3年5个月"。
为什么我在函数列表里找不到 DATEDIF? ⭐ 因为它通常不出现在提示列表里(所以常被叫做"隐藏函数")。 功能是有效的,把公式完整手输进去就能用。
为什么我把公式往下拉,结果就错了? ⭐ 多半是引用没有锁列——改成 $A2(列钉住、行跟着走)就能正常填充。
为什么我的时间差算出来不对? 最常见的原因是"日期其实是文本"。 ⭐ 判断方法:真正的日期默认靠右,文本默认靠左;或者把它加 1,看会不会变成第二天。
用了 TODAY() 的表,为什么数字天天在变? ⭐ 因为 TODAY() 取的是当天日期——这既是它的优点(工龄自动更新),也是留档时的麻烦。 需要固定时,用"选择性粘贴 → 数值"把公式转成数字。
"ym" 和 "md" 是什么意思? ⭐ "ym" 是"不满一年的月数","md" 是"不满一月的天数"。 ⚠️ 其中 "md" 在涉及月末等边界情况时结果可能不符合直觉,建议抽查。
DATEDIF 算出来的月数,和我自己按月数的对不上,为什么? ⭐ 因为它算的是"完整月"——不满一个月的那部分不会计入 "m",这正是需要 "ym" 和 "md" 去拿零头的原因。 ⚠️ 而"跨月怎么算"本身和行业口径有关,必要时和同事统一一次。
能算两个日期之间有几个周末或工作日吗? ⚠️ 这需要另外的函数组合,DATEDIF 不做这件事。 ⭐ 它的定位很明确:给你"日历上的差",而不是"按工作日排的差"。
把这篇压成三句话:
先分清需求:要"一共多少天"就直接相减,要"几年几个月"就用 DATEDIF——因为天数有唯一答案,而"年月"取决于你按哪个单位算。 DATEDIF 有一个实际障碍:它通常不出现在函数提示里,得手输完整公式;而它真正的价值在于 "ym" 这类单位——"y" 只给满年数,"ym" 才补上多出来的月份。 两个最该记住的细节:往下填充时引用要锁列($A2);以及用了 TODAY() 的表是"活的",留档之前记得把公式转成数值。
最后一句话:算时间差的难点不在函数,而在两个前提——"那两格得是真日期",以及"你要的是天数还是年月"。
没有相关标签