日期和时间:算工期算年龄

日期在 Excel 眼里就是数字

Excel日期的底层逻辑

上一篇说过日期本质是整数:1900 年 1 月 1 日是 1,每天加 1,2026 年 10 月 26 日是 46290。时间是小数:一天是 1,所以 9 点是 0.375,中午 12 点是 0.5。这套机制一旦接受,所有日期计算就跟数字计算没有区别。

理解这点能解释很多怪事。比如直接输入 10/26 期望是 10 月 26 日,有时候得到的是 10 月 26 日没错(当年),有时候被当成除法 10÷26。再比如两个日期相减直接得到天数差:=B2-A2 得到工期 23 天。不需要任何函数。整数特性还解释了为什么 WEEKNUM、EOMONTH 这些函数算 Tuesday、月末——它们本质是整数游戏。

输入日期用三种分隔符都会被识别:2026-10-26、2026/10/26、2026.10.26 有时候也认(看版本和地区设置)。但 2026.10.26 在很多环境里被判为文本,排序和计算全部失效,是日期里最大的坑。外贸和统计表格里常见这种 圆点日期,正规化先做:分列走一遍,或用 SUBSTITUTE 把点换成横杠再配上文本转日期。如果你习惯敲键盘,也可以用 DATE(年,月,日) 函数拼:=DATE(2026,10,26),最不容易出岔子。

时间输入同样有讲究:9:30 会自动识别为上午 9 点 30,14:00 也行,2 PM 不一定认识。显示上日期加时间会在一个格子里同时显示。要让一个同时含日期时间的单元格显示好,F2 后 Ctrl+1 调格式:yyyy-mm-dd hh:mm 是最清晰的组合写法。相关类型知识在单元格和数据类型里。

日期加减和常用日期函数

算工期最简单的形态:开始日期在 A2,结束日期在 B2,=B2-A2 得到自然天数。但这是纯天数,没扣周末。扣周末的工具有 NETWORKDAYS:=NETWORKDAYS(A2,B2) 返回两个日期之间的工作日数,自动跳过周六周日。假期也要扣?第三个参数放节假日区域:=NETWORKDAYS(A2,B2,$H$2:$H$30),把公司放假表填进去,年假、法定假一起算掉。

函数 返回 典型用法
=B2-A2 天数差 自然天数
NETWORKDAYS 工作日数 =NETWORKDAYS(A2,B2,假期区)
NETWORKDAYS.INTL 自定义周末的工作日 =NETWORKDAYS.INTL(A2,B2,11)
WORKDAY 几个工作日后的日期 =WORKDAY(A2,10)
DATEDIF 年/月/日差 =DATEDIF(A2,B2,"Y")
EOMONTH 月末日期 =EOMONTH(A2,0)

排项目计划常用 WORKDAY:从今天起 10 个工作日后是哪天,=WORKDAY(TODAY(),10),返回一个日期,自动不落在周末。第三个参数同样能放假期表。WORKDAY 的兄弟 WORKDAY.INTL 更灵活,可以指定哪几天算周末:参数 11 表示周日单休,12 表示周日和周一双休之外的各种组合。做中东项目或者特殊排班时会用到。

DATEDIF 是个有趣的函数:Excel 帮助里几乎不提它,但特别好用。算年龄的经典写法:=DATEDIF(A2,TODAY(),"Y") 得到周岁。第三个参数决定返回什么:Y 是整年数、M 是整月数、D 是总天数、YM 是去掉整年后的月数、MD 是去掉整年整月后的天数。算工龄精确到几年几月:=DATEDIF(A2,B2,"Y")&"年"&DATEDIF(A2,B2,"YM")&"个月"。

EOMONTH 是月度报表的常客:=EOMONTH(A2,0) 返回 A2 所在月份的最后一天,=EOMONTH(A2,1) 是下月末,负数是上月末。配合 DAY 还能算出一个月有几天:=DAY(EOMONTH(A2,0)),做分母算日均指标时很好用。EDATE 是它的孪生兄弟,=EDATE(A2,3) 得到三个月后的同一天,算合同到期日、质保截止日全靠它,比手工数月份靠谱得多,尤其是跨年的时候。

还有两个经常被忽略的工具。TODAY() 返回今天的日期,NOW() 返回此刻的日期时间,两者都不带参数(括号里是空的),每次打开工作簿会自动刷新。它们的价值在于让表活起来:=TODAY()-A2 得到应收账款挂了几天,=IF(TODAY()-A2>90,"超期 90 天","正常") 直接把账龄标出来。需要注意的是 TODAY 是易失函数,每次重算都会变,如果你要的是固定时间戳,应当按 Ctrl+; 输入静态日期,两者别混用。

WEEKNUM 和 ISOWEEKNUM 用来算第几周:=WEEKNUM(A2) 返回这个日期是该年的第几周,做周报分组合适。ISOWEEKNUM 按国际标准算(周一为一周起点,含四个以上天数的第一周算第一周),跨国团队协作时用它能避免周数对不上。按周汇总订单量的时候,加一列周数再交给数据透视表,比按日期分组干净得多。

需求 写法 说明
三个月后的日期 =EDATE(A2,3) 合同到期、质保
本月最后一天 =EOMONTH(A2,0) 月度截止
本月有多少天 =DAY(EOMONTH(A2,0)) 算日均
该年第几周 =WEEKNUM(A2) 周报分组
今天 =TODAY() 易失,自动刷新
静态当天 Ctrl+; 不随重算变化
挂账天数 =TODAY()-A2 账龄分析

EOMONTH 是做月度报表的核心。=EOMONTH(A2,0) 返回当月最后一天,1 是下个月最后一天,-1 是上个月。月度汇总的起止日期都能用它推:月初是 =EOMONTH(A2,-1)+1。另外 TODAY() 返回今天的日期,NOW() 返回今天的日期加当前时间,做登记表里 自动显示当前时间 很方便。

时间计算和格式

时间比日期更容易出怪事。最经典:加班时长 21:00 减 18:30,=B2-A2 得到 2:30,这很正常。但如果跨过零点——加班到凌晨 2 点,结束时间 2:00 比开始时间还小,减出来是负数,Excel 直接显示一串井号(早期版本是真负不了,显示 ####)。跨零点的修正写法:=B2-A2+IF(B2<A2,1,0),结束小于开始就加一天的时间量,凌晨班次问题解决。

算出来的时长是几点几分这种 格式,用来做统计会被坑。2:30 的时长,它的底层是 0.1042,不是 2.5 小时。要换算成小时数参与计费:=(B2-A2)24,得到 2.5。按分钟算就 1440。做题考勤工时、算加班费,这一步乘法必不可少。乘出来之后记得把格式设为常规,否则还是显示成时间。

报表里常见的时间格式代码:hh:mm 是 24 小时制的时:分,hh:mm:ss 带秒数,[h]:mm 是超过 24 小时不进位的总时长。最后一个是灵魂:一个工作人员连续工作 26 小时,用 hh:mm 显示会变成 02:00,用 [h]:mm 就保持 26:00。任何累计时长的场合都要记得加方括号。

显示要求 格式代码 例子
24 小时制 hh:mm 21:30
精确到秒 hh:mm:ss 21:30:45
累计小时 [h]:mm 26:00
中文日期 yyyy 年 m 月 d 日 2026 年 10 月 26 日
含英文月 mmm d, yyyy Oct 26, 2026
带月份缩写 中文 mm 月 dd 日 10 月 26 日

提取日期成分和文本日期转换

从完整日期里单独取年、月、日:=YEAR(A2)、=MONTH(A2)、=DAY(A2),这三个函数直观易记。做分组统计时常见:=MONTH(A2) 把一列订单按月份拆开,再做 SUMIFS 分类汇总。=WEEKDAY(A2) 返回 1 到 7,表示星期几(第二参数决定一周从哪天开始,2 表示周一为 1)。判断今天是否周末:=WEEKDAY(TODAY(),2)>5。

文本日期转真日期有两个门口。分列法:选中列,数据、分列,第三步选 日期 和 YMD 顺序,走完即活。函数法:DATEVALUE 函数 =DATEVALUE("2026-10-26"),但它对加点写法 2026.10.26 这种不规范的文本无能为力。万能做法是 SUBSTITUTE 换成横杠再 DATEVALUE:=DATEVALUE(SUBSTITUTE(A2,".","-"))。

反向需求:日期变文本。=TEXT(A2,"yyyy-mm-dd") 直接得到字符串形式的日期,做卡号、单号拼接常用。注意拼起来之后这个字符串就不再能算差了,文本函数那篇有更完整的拼接技巧。

提取生日做生日提醒是温暖的应用:员工表 A 列是生日(不带年份的日期),提醒公式 =IF(MONTH(A2)=MONTH(TODAY()),IF(DAY(A2)=DAY(TODAY()),"今天生日","本月生日"),"")。再配合条件格式,员工生日表自己做提醒,不用人盯。

工作日计算:排工期离不开的 NETWORKDAYS 家族

真实项目里,工期不是简单的结束日期减开始日期,周末和法定节假日要刨掉。Excel 提供了三个现成的函数。NETWORKDAYS(开始日期,结束日期,假期区域)算两个日期之间有几个工作日;WORKDAY(开始日期,天数,假期区域)反着算,从某天往后推 N 个工作日是哪天;NETWORKDAYS.INTL 和 WORKDAY.INTL 是加强版,可以自定义哪几天是周末,单休、轮休都能支持。

举个排工期的例子。一个项目 2026 年 11 月 2 日启动,合同约定 15 个工作日交付,期间 11 月 8 日到 11 月 10 日放假调休。交付日公式:=TEXT(WORKDAY(DATE(2026,11,2),15,$G$2:$G$4),"yyyy 年 m 月 d 日"),其中 G 列预先放好假期日期。如果有人问这 15 个工作日实际跨了几个自然日,用 NETWORKDAYS 反向验证一下天数对不对即可。

INTL 版本的第二个参数用 11 位的 0 和 1 组成周末代码,1 代表休息,最常用的几种列在下面:

周休方式 周末代码 结果
双休(周六周日) 1 或 0000011 默认值
单休(周日) 17 或 0000001 常见单休制度
周五周六休息 4 或 0011000 中东地区节奏
自定义字符串 "1010100" 逢单休息等排班
一周无休 0 全周工作

自定义代码从星期一 pos 开始排,第一位对应周一。轮班制企业做排班表时这个参数特别好用,比手工维护一张休息日清单省事得多。

年龄和司龄:DATEDIF 的正确打开方式

DATEDIF第三参数对照

DATEDIF 是个隐藏函数,函数列表里翻不到它,输入却有提示。它的作用是算两个日期之间隔了几年几月几天,语法 =DATEDIF(开始日期,结束日期,"间隔代码")。间隔代码区分大小写:第三参数 "Y" 算整年数(算虚岁还是周岁就靠它),"M" 算整月数,"D" 算天数,"YM" 算刨掉整年后剩几月,"MD" 算刨掉整年整月后剩几天。

人事场景最常用:=DATEDIF(B2,TODAY(),"Y") 算员工司龄的整年数,配合 =DATEDIF(B2,TODAY(),"YM") 得到零头月数,拼成 3 年 4 个月这种人性化表述:=DATEDIF(B2,TODAY(),"Y")&" 年 "&DATEDIF(B2,TODAY(),"YM")&" 个月"。身份证号里抠生日也能用,=DATEDIF(DATE(MID(B2,7,4),MID(B2,11,2),MID(B2,13,2)),TODAY(),"Y") 得到周岁年龄。注意 MID 抠出来的位置以 18 位身份证为准,15 位老证件不适用。

合同到期提醒是同一家族的经典应用:=IF(DATEDIF(TODAY(),C2,"D")<30,"快到期","正常"),C 列放合同截止日。这里开始日期是今天,结束日期是将来的合同日,顺序不能颠倒,颠倒了直接 #NUM!。

日期在统计和展示里的两个用法

日期最容易被低估的价值是分组统计。销售流水表里每行一个订单日期,老板要看每个月的销售额,新手会先插一列用 MONTH 算月份再求和,其实数据透视表直接把日期字段拖到行区域,右键选择组合,按月、按季度、按年自动分组,一行公式都不用写。组合功能要求这一列必须是真日期,文本日期会报 无法组合,这又绕回了开头那句:日期必须是数字。

第二个用法是日期区间判断。考勤表里判断打卡是否迟到:=IF(B2>TIME(9,0,0),"迟到",""),TIME 函数把 9 点 0 分 0 秒拼成时间值,比写 "9:00" 这种文本稳得多。合同表里判断是否已进入最后一个月:=AND(C2-TODAY()>=0,C2-TODAY()<=30),配条件格式把快到期的行整行标黄,到期提醒表就做成了。AND 里两个条件同时成立才返回 TRUE,这类区间判断在日期场景里出现频率极高。

做甘特图也是同一套底层。开始日期一列、工期天数一列,用堆积条形图把开始日期画成透明的辅助条、工期画成彩色条,一张最简单的项目进度图就出来了。Excel 没有专门的甘特图类型,但用条形图加日期轴拼一个完全够用,比装插件轻。

最后讲一个跨区域的坑:1900 日期系统和 1904 日期系统。Windows 版 Excel 默认用 1900 系统,Mac 老版本有的用 1904,两个系统的同一天底层数字差 1462。跨 Mac 和 Windows 传文件时,日期会整体偏移四年多,看起来莫名其妙。排查办法是随便找个已知日期的数字值对一下,差 1462 就是这个原因。修法在 Excel 选项的高级里找 使用 1904 日期系统 这个勾,两边保持一致即可。遇到这个坑的人往往查了几天才想到,记住 1462 这个数字能省下你不少时间。

再补一条录入技巧:输入今天的日期按 Ctrl+;,输入当前时间按 Ctrl+Shift+;,两个都是快捷键直接写死,不走函数,不会因为重算而变。做签到表、做记录台账时比 TODAY 合适。想同时写日期和时间,先按 Ctrl+; 再空格再 Ctrl+Shift+;,一次搞定。

最后给一条自查口诀:凡是日期算出来不对,先查它是不是真日期。选中单元格看编辑栏,左边对齐的多半是文本,右边对齐的大概率是真日期;再用 =ISNUMBER(A2) 确认一次,返回 FALSE 就说明它还是文本。这一步判断只花五秒,却能省掉后面半小时的无效排查。日期是所有表格里最容易出隐性错误的数据类型,因为它看起来永远是对的,错的是算出来的结果。养成先验证再计算的习惯,你就超过了八成的使用者。整本书里关于日期的部分,你只要记住三件事就够用一辈子:日期是数字、文本日期要转真日期、累计时长格式要加方括号。其余的函数和快捷键,用到时再查也不迟。

相关篇章

日期经常是条件的一部分——本月销售额、近 30 天订单——IF 和多条件判断里的 AND、IFS 配合日期函数是固定组合。日期类型出问题多半因为文本混在其中,SUM 家族里错误值排查的思路同样适用于日期。

常见问题

为什么显示 2026/10/26 的日期无法相减或排序?

说明它其实是文本,只是长得像日期。检验:=ISNUMBER(A2),TRUE 才是真日期。正规化途径:分列向导第三步选日期,或者 SUBSTITUTE 换分隔符后 DATEVALUE。批量处理时,先检查一整列用 ISNUMBER 和定位条件,把文本日期一次性圈出来。

两个日期相减结果显示一个日期而不是天数?

因为公式引用了两个日期,Excel 自动把结果也按日期格式显示。选中结果单元格,Ctrl+1 把格式改成常规或数字,天数就出来了。也可以在公式里直接控制:=(B2-A2) 配合格式,或者 =B2-A2 之后按 Ctrl+Shift+~(设为常规的快捷键)。

DATEDIF 提示 #NUM! 错误?

DATEDIF 要求第二个日期不小于第一个日期,否则报错。检查两个参数的顺序,或者用 =IF(B2<A2,DATEDIF(B2,A2,"Y"),DATEDIF(A2,B2,"Y")) 兜底。另一个隐藏要求是开始日期不能早于 1900 年 1 月 1 日,历史数据表可能出这种问题。

加班时长显示 02:00 但实际是 26 小时?

格式在作怪。时长超过 24 小时后,标准时间格式会回卷到 0。把格式改成 [h]:mm,Excel 就显示 26:00 了。同理,累计到分钟用 [m],累计到秒用 [s]。改完格式数字本身没变,变的只是显示方式,参与计算不受影响。

NETWORKDAYS 或 WORKDAY 报错或结果不对?

检查三件事:日期参数是否真日期(文本日期会让结果完全错乱);假期区域的日期格式是否规范;函数拼写对不对(NETWORKDAYS 是一个词,不少人写成 NETWORK DAYS)。假期区域里混入文本或空行也会让某些版本跳过整个参数。