日期时间戳的双向转换
Excel 里的日期本质是一个整数:1900 年 1 月 1 日是 1,往后每天加 1。2026-10-20 大约就是 46307。时间则是小数部分,中午 12 点是 .5。
理解这一点,"日期变数字""数字变日期""加减天数不对"这类问题都能自己解释。
一、日期 → 序列值
最快的办法是把单元格格式改成"常规",值就露出来了。函数写法:
=VALUE(A2)
=A2*1
算两个日期差多少天,直接相减:
=B2-A2
结果单元格可能显示成日期,改回常规即可。算整月、整年差用 DATEDIF:
=DATEDIF(A2,B2,"M")
=DATEDIF(A2,B2,"Y")
二、序列值 → 日期
=TEXT(A2,"yyyy-mm-dd") ' 转成文本
=A2 ' 套日期格式,值不变
如果单元格里是文本 2026/10/20,先转成日期值:
=DATEVALUE(A2)
DATEVALUE 认系统日期格式,中文环境下 2026年10月20日 也认。换语言环境就没那么可靠了。
三、拼接与拆分
把年、月、日三列拼成一个日期:
=DATE(A2,B2,C2)
别用 A2&"-"&B2&"-"&C2,那得到文本,排序时 2026-9-1 会跑到 2026-10-1 后面。
反过来拆:
=YEAR(A2)
=MONTH(A2)
=DAY(A2)
四、加减日期
=A2+7 ' 7 天后
=A2-1 ' 前一天
=EDATE(A2,3) ' 3 个月后,自动处理月末
=EOMONTH(A2,0) ' 本月最后一天
=EOMONTH(A2,-1)+1 ' 本月第一天
EDATE 和 EOMONTH 是处理月末唯一可靠的办法。1 月 31 日加一个月,A2+30 会得到 3 月 2 日,EDATE(A2,1) 才得到 2 月 28 日。
五、工作日计算
=WORKDAY(A2,10) ' 10 个工作日后的日期
=NETWORKDAYS(A2,B2) ' 两日期间工作日数
=NETWORKDAYS(A2,B2,节假日区域) ' 排除法定节假日
把节假日单独放一列,每年更新一次,NETWORKDAYS 第三个参数传这个区域。调休上班的日子不支持自动加回,需要手工调整。
六、时间部分
=TIME(9,30,0) ' 9:30
=A2-INT(A2) ' 取出时间部分
=INT(A2) ' 取出日期部分
=(B2-A2)*24 ' 工时,带小数
时长显示有个关键点:超过 24 小时必须用 [h],否则 30 小时会显示成 6 小时。
=TEXT(B2-A2,"[h]:mm")
七、导入 CSV 的日期灾难
系统导出的 CSV 里日期变成 #VALUE! 或荒谬的年份,通常是源数据用美式 MM/DD/YYYY,被按 DD/MM/YYYY 解析了。
正确做法:导入时在向导里把列格式显式指定为"日期",并选对 MDY/DMY,别让它自动判断。
已经导坏的,如果原值是 10/20/2026 这种纯文本,可以手工重拼:
=DATE(RIGHT(A2,4),LEFT(A2,2),MID(A2,4,2))
八、常见坑
- 日期相减结果是个日期:把结果单元格格式改回常规。
TODAY()不更新:计算方式被设成了手动,改"公式 → 计算选项 → 自动"。- 日期排序乱:列里混着文本日期和真日期,用
ISNUMBER找出文本项统一转换。 - 1900 年问题:Excel 为兼容 Lotus 1-2-3 把 1900 年当闰年,算 1900 年 3 月以前的日期会有偏差,业务上基本遇不到。
九、速查
| 需求 | 公式 |
|---|---|
| 天数差 | =B2-A2 |
| 月数差 | =DATEDIF(A2,B2,"M") |
| 文本转日期 | =DATEVALUE(A2) |
| N 个月后 | =EDATE(A2,N) |
| 月末 | =EOMONTH(A2,0) |
| 工作日 | =NETWORKDAYS(A2,B2,节假日) |
| 超 24 小时时长 | =TEXT(B2-A2,"[h]:mm") |
日期的值和方法要分清:格式只管显示,值才是数据。把两者搞混,是大部分日期问题的根源。