合同到期日推算
某创业公司 HR 在 3 月 15 日签下一名新员工,合同约定试用期 6 个月。她需要精确算出试用期截止日(9 月 15 日),以及转正审批必须完成的最后时限。手动翻日历数 6 个月容易看错,尤其当起始日是月底或跨年时。直接用工具输入 2025-03-15,加 6 个月,结果秒出,避免因算错一天导致转正流程延误的劳动纠纷风险。
项目排期常卡在「下周五」到底是加 7 天还是加 5 个工作日;合同截止日「3 个月后」碰上闰月该不该多算一天。输入起始日期和偏移量(±N 天/周/月/年),它直接给出结果,不绕弯子。所有计算在浏览器内完成,不经过服务器,数据不上传。
某创业公司 HR 在 3 月 15 日签下一名新员工,合同约定试用期 6 个月。她需要精确算出试用期截止日(9 月 15 日),以及转正审批必须完成的最后时限。手动翻日历数 6 个月容易看错,尤其当起始日是月底或跨年时。直接用工具输入 2025-03-15,加 6 个月,结果秒出,避免因算错一天导致转正流程延误的劳动纠纷风险。
业主计划 10 月 1 日搬家,装修公司承诺工期 45 天。他需要倒推出最晚开工日期:8 月 17 日。但中间涉及中秋、国庆假期,工人可能停工,实际有效工期不足。他用工具先算出 8 月 17 日加 45 天是 10 月 1 日,再分别减去 3 天中秋假和 7 天国庆假,得到 7 月 28 日必须开工。这个数字直接写进合同,防止装修队以“算错日子”为由延期。
某用户账单日为每月 5 日,最后还款日为账单日后 20 天。他 4 月 5 日出账,按“加 20 天”算出 4 月 25 日还款。但 5 月账单日遇到 5 月 5 日(劳动节假期),银行顺延至节后第一个工作日(5 月 6 日)出账,还款日变成 5 月 26 日。他用工具分别验证 4 月 5 日+20 天和 5 月 6 日+20 天,两次结果相差 1 天,及时调整了自动扣款设置,避免了因假期调整产生的逾期。
医生给一位慢性病患者开了 28 天的药,要求每日 2 次,每次 1 片。患者从 6 月 1 日开始服药,想知道药吃完那天(6 月 28 日)是否正好赶上复诊日。他用工具输入 6 月 1 日加 28 天,得到 6 月 29 日——比预计多出 1 天,因为 6 月只有 30 天。他据此把复诊预约从 6 月 28 日改到 6 月 29 日,避免了断药风险。
产品经理在 7 月 10 日启动一个 90 天的开发项目,需要设定 3 个里程碑:第 30 天(原型评审)、第 60 天(内测)、第 90 天(上线)。他用工具分别算出 8 月 9 日、9 月 8 日、10 月 8 日。其中 10 月 8 日正好是国庆假期后第一天,他提前把上线日调整到 10 月 9 日,避开假期运维人手不足的窗口,这个调整被写进了项目章程。
| 维度 | 本工具 | 在线日历/计算器站 | 手动翻日历/笔算 |
|---|---|---|---|
| 计算范围 | ±9999 年(年/月/日/周/天) | 通常限 ±100 年,部分不支持周 | 受限于手头日历年份,超 100 年极难 |
| 隐私 | 纯浏览器计算,数据不上传服务器 | 需提交到服务器,有日志记录 | 完全离线,无数据留存 |
| 速度 | 输入即出结果,零网络延迟 | 依赖网络请求,约 0.5-2 秒 | 需逐月数/逐日算,数分钟至数小时 |
| 闰年/月处理 | 自动处理公历闰年、每月天数差异 | 多数支持,但部分老旧站点算法有误 | 极易漏算闰年 2 月 29 日,需手动核对 |
| 离线可用 | 页面加载后可断网使用 | 每次计算需联网 | 完全离线 |
| 输入 | 输出 | 说明 |
|---|---|---|
| 2024-03-01 + 30 天 | 2024-03-31 | 常规:跨月加法,验证工具正确处理 3 月有 31 天,而非简单加 30 天得到 2024-03-31(正确)或 2024-04-01(错误) |
| 2024-02-29 + 1 年 | 2025-02-28 | 边界:闰年 2 月 29 日加 1 年,目标年 2025 年非闰年,工具应自动回退到 2 月 28 日,而非报错或输出 2025-03-01 |
| 2023-01-31 + 1 月 | 2023-02-28 | 边界:月末加月,1 月 31 日加 1 月,2 月只有 28 天(非闰年),工具应回退到 2 月 28 日,而非跳到 3 月 3 日 |
| 2024-01-01 - 1 天 | 2023-12-31 | 常规:跨年减法,验证工具正确处理年份边界,返回 2023 年 12 月 31 日而非报错 |
| 2024-01-01 + 0 天 | 2024-01-01 | 边界:加 0 天,验证工具不改变原日期,且不产生空结果或异常 |
| 2024-06-15 + 2 周 | 2024-06-29 | 常规:周为单位加法,2 周 = 14 天,验证工具正确将周转换为天数计算,而非按周数取整 |
| 2024-02-28 + 1 年 | 2025-02-28 | 易错:闰年 2 月 28 日加 1 年,目标年 2025 年非闰年,2 月 28 日存在,工具应保持日期不变,而非误跳到 2 月 27 日或 3 月 1 日 |
| 2024-12-31 + 1 天 | 2025-01-01 | 易错:年末最后一天加 1 天,验证工具正确处理年份进位,返回下一年 1 月 1 日而非 2024-01-01 |
1.加减天数时,月份边界处理错误
2024-01-31 加 1 个月,期望得到 2024-02-312024-01-31 加 1 个月 → 2024-02-29(闰年)或 2024-02-28(平年)不同月份天数不同,日期计算工具通常会自动截断到当月最大有效日,不会产生 2 月 31 日这种无效日期。
2.跨年时周数计算混淆
2023-12-31 是周日,认为它是 2023 年第 1 周2023-12-31 属于 2024 年第 1 周(ISO 8601 标准)ISO 8601 定义:包含该年第一个周四的周为第 1 周。12 月 31 日若在周四之前,可能归属下一年第 1 周。
3.加减年数时忽略闰日影响
2020-02-29 加 1 年,期望 2021-02-292020-02-29 加 1 年 → 2021-02-28闰年 2 月 29 日加非闰年时,目标日期不存在,工具自动回退到 2 月 28 日。
4.日期格式混用导致解析失败
输入 01/02/2024 期望是 2024 年 1 月 2 日输入 2024-01-02 或明确选择格式(月/日/年 或 日/月/年)月/日/年 和 日/月/年 歧义(如 01/02/2024 可能是 1 月 2 日或 2 月 1 日),工具默认按 ISO 8601 格式 YYYY-MM-DD 解析。
5.时区未指定导致日期偏移
UTC+8 用户输入 2024-01-01 00:00,工具按 UTC 计算得到 2023-12-31工具明确标注使用 UTC 或本地时区,输入时按工具要求选择时区纯前端 Date 对象默认使用浏览器本地时区,若后端处理则可能用 UTC,跨时区用户需注意结果可能差一天。
6.负数输入时符号位置错误
输入 -5 天,但工具只接受正数加负号前缀,写成 5-输入 -5 或选择减法模式日期计算工具通常要求负号紧贴数字前(-5),而非数字后(5-),后者会被解析为无效输入。
7.忽略闰秒对精确计算的影响
计算 2016-12-31 到 2017-01-01 的秒数,期望 86400实际为 86401 秒(2016 年 12 月 31 日有闰秒)UTC 时间系统在 2016 年底插入闰秒,导致该日有 86401 秒。普通日期计算工具通常忽略闰秒,高精度场景需注意。
8.月份加减时误解 '加 1 月' 含义
2024-01-31 加 1 月,期望 2024-02-28(认为自动对齐到月底)2024-01-31 加 1 月 → 2024-02-29(闰年)或 2024-02-28(平年),若期望月底则需手动处理日期计算按月份递增月份数,然后截断无效日,并非自动对齐到月底。
目标日期 = 起始日期 ± (天数 + 周数×7 + 月数×30 + 年数×365)
起始日期用户输入的基准日期天数要加减的天数,整数周数要加减的周数,整数月数要加减的月数,整数年数要加减的年数,整数起始日期 2024-02-28,加 1 年、2 月、3 周、5 天:先加年得 2025-02-28,加月得 2025-04-28,加周(3×7=21天)得 2025-05-19,加天得 2025-05-24。最终结果 2025-05-24。
5 种主流语言实现,复制即用:
from datetime import datetime, timedelta
def date_add(start: str, days: int = 0, weeks: int = 0, months: int = 0, years: int = 0) -> str:
dt = datetime.strptime(start, "%Y-%m-%d")
# 月份/年份加减需逐月处理,避免 timedelta 不支持
month = dt.month + months + years * 12
year = dt.year + (month - 1) // 12
month = (month - 1) % 12 + 1
day = min(dt.day, [31,29 if year%4==0 and (year%100!=0 or year%400==0) else 28,
31,30,31,30,31,31,30,31,30,31][month-1])
dt = dt.replace(year=year, month=month, day=day)
dt += timedelta(days=days, weeks=weeks)
return dt.strftime("%Y-%m-%d")
print(date_add("2024-02-29", days=1)) # 2024-03-01
print(date_add("2024-01-31", months=1)) # 2024-02-29(月末对齐)function dateAdd(start, { days = 0, weeks = 0, months = 0, years = 0 } = {}) {
const d = new Date(start);
// 先处理月份/年份,再处理天/周,避免跨月问题
d.setMonth(d.getMonth() + months + years * 12);
d.setDate(d.getDate() + days + weeks * 7);
return d.toISOString().slice(0, 10);
}
console.log(dateAdd("2024-02-29", { days: 1 })); // 2024-03-01
console.log(dateAdd("2024-01-31", { months: 1 })); // 2024-03-02(JS 自动溢出)package main
import (
"fmt"
"time"
)
func dateAdd(start string, days, weeks, months, years int) string {
dt, _ := time.Parse("2006-01-02", start)
// 月份/年份:先加月,再调日(避免 31→30 等溢出)
dt = dt.AddDate(years, months, 0)
dt = dt.AddDate(0, 0, days+weeks*7)
return dt.Format("2006-01-02")
}
func main() {
fmt.Println(dateAdd("2024-02-29", 1, 0, 0, 0)) // 2024-03-01
fmt.Println(dateAdd("2024-01-31", 0, 0, 1, 0)) // 2024-02-29(Go 自动月末对齐)
}#!/bin/bash
# 依赖 GNU date(Linux 默认),macOS 需 brew install coreutils 并改用 gdate
date_add() {
local start=$1
local days=${2:-0}
local months=${3:-0}
local years=${4:-0}
# 先处理月份/年份(date -d 支持相对月/年)
local tmp=$(date -d "$start +$months months +$years years" +%Y-%m-%d)
date -d "$tmp +$days days" +%Y-%m-%d
}
date_add 2024-02-29 1 0 0 # 2024-03-01
date_add 2024-01-31 0 1 0 # 2024-02-29(GNU date 自动月末对齐)import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
public class DateAdd {
public static String dateAdd(String start, int days, int weeks, int months, int years) {
LocalDate dt = LocalDate.parse(start);
// 先加月份/年份,再加天/周
dt = dt.plusMonths(months + years * 12L);
dt = dt.plusDays(days + weeks * 7L);
return dt.toString();
}
public static void main(String[] args) {
System.out.println(dateAdd("2024-02-29", 1, 0, 0, 0)); // 2024-03-01
System.out.println(dateAdd("2024-01-31", 0, 0, 1, 0)); // 2024-02-29(Java 自动月末对齐)
}
}不会。本工具是纯日历天数累加,不识别任何节假日、工作日或调休。90天后就是今天+90天,不管中间有没有春节、国庆或周末。如果需要跳过法定假日,需要配合「工作日计算」类工具使用。
不是错,是闰日处理的常见规则。2024年2月29日加1年,由于2025年不是闰年、没有2月29日,工具自动顺延到下一日即3月1日。大部分日期计算工具都采用这种「月末顺延」逻辑。如果你希望固定得到「同年同月同日不存在则取当月最后一天」,需选择「月末截断」模式,本工具默认采用顺延逻辑。
3月31日减1个月,工具先减月份到2月31日,但2月只有28或29天,所以自动顺延到3月3日(2月28日+3天)。这是标准算法。如果你希望得到2月28日(即「当月最后一天」),需要理解本工具采用的是「跨月顺延」而非「月末截断」规则。两种规则在日期计算领域都有使用,本工具默认使用前者。
因为「周」的计算不是简单天数÷7取整。本工具按「完整7天为一周」计算:比如从周一0点到下周一0点算1周,但周一0点到周日24点只有6天,算0周。所以当你看到「相差10天,0周」是合理的——10天跨越了1个完整周再加3天,但完整周数只有1周(实际显示1周3天)。建议主要看天数,周数只作为辅助参考。
Excel的DATE函数在跨月处理上采用「月末截断」规则,而本工具采用「顺延」规则,所以遇到2月29日、3月31日这类边界日期时结果可能不同。两种算法没有谁更准,只是约定不同。Excel是财务领域常用规则,本工具是通用日历计算规则。建议根据你的使用场景选择:合同日期建议按Excel规则,日常倒计时用本工具即可。
大概率不是工具问题,而是浏览器日期输入框的兼容性。部分国产安卓浏览器(如旧版UC、QQ浏览器)对<input type="date">支持不完整,点击没弹出日期选择器。可以尝试:1. 手动在输入框里按「YYYY-MM-DD」格式直接打字;2. 换Chrome或系统自带浏览器;3. 如果页面有「点击输入」按钮,点那个代替。本工具纯前端运行,不依赖服务器,浏览器正常就能用。
因为2020年是闰年,2月有29天。加1年时,工具先加年份到2020年,然后保持月日不变,得到2020年2月28日——这个日期在2020年是存在的,所以不会顺延。如果你得到2020年2月29日,请检查是不是输入了「2019年2月29日」(不存在)或者操作了「加1年1天」。2019年2月28日加1年一定是2020年2月28日,这是准确的。
本工具采用「日期差=结束日期-开始日期」的标准算法,不包含开始日当天。所以2023-01-01到2024-01-01的结果是365天(2023年全年天数)。如果你需要「包含头尾」的算法(如计算合同覆盖天数),结果应该是366天。本工具没有「是否包含首日」的开关,建议根据业务场景手动+1或-1。法律文书建议以实际合同条款描述为准。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。