天周计算器

把天数、周数、月数互相换算,并把「一个月到底算多少天」的四种口径并排算给你看:30 天制月、公历平均月 30.436875 天、按起始日期逐月推进的日历月、朔望月 29.530588853 天。

提示:数值框和起始日期框里按 Enter 可直接重算。上面这批卡片是「100 天、起始日期 2026-03-01」的默认结果。

使用方法

  1. 在「数值」填 100(示例值),允许 0.01~1000000 之间的小数;在「输入单位」选「天」。
  2. 「起始日期」填 2026-03-01(示例值)。它在三种口径下起作用:算「日历月」时要从这里逐月往后推,算「落点日期」时要拿它加天数,算「加载更多」后的整张对照表也以它为锚点。只算周、30 天制月和公历平均月的话,这一格不影响结果。
  3. 按 Enter 或点「开始换算」。结果区 12 张卡片同时给出总天数、周 + 天、周数小数、三种月数、两种年数、日历月、落点日期、小时与分钟。
  4. 看「月(30 天制)」和「月(公历平均)」这两张卡片:同一批天数,两个数不相等,这就是本页最重要的口径差别。100 天是 3.3333 个 30 天制月,却只有 3.2855 个公历平均月,差了约 1.46 天。
  5. 「日历月(自锚点)」这一格给出的是最贴近日常说法的答案:从起始日期起最多能推几个整月、还剩几天。100 天从 2026-03-01 起是 3 个月 8 天,落点是 2026-06-09。
  6. 下方对照表共 20 行,先显示 12 行,点「加载更多」展开其余 8 行;「导出 CSV」自带 BOM,Excel 双击不乱码;「复制对照表」复制的是制表符分隔的 TSV,可直接粘进表格。
  7. 点「重置为默认示例」随时回到「100 天 / 2026-03-01」这组默认值。

这个天周计算器能解决什么问题

一是把「几个月」这句话变成可核对的数字。合同写「三个月内交付」,90 天、92 天还是 91 天?本页告诉你:90 天是 3 个整 30 天制月,但从 2026-03-01 起算的 90 天只有 2 个月 29 天,因为三月有 31 天。要签合同、算工期、排交付节点时,先确认用的是哪一种月,比事后争论便宜得多。

二是对齐两套常见惯例。会计与金融常用 30 天制月、360 天年(ISDA 30/360 天数计算惯例),排期与日历常用真实的日历月和格里高利年。本页把两套并排显示,同一批天数在两个体系里各是多少个月、差几天,一眼可见,不用来回换工具。

三是反推落点日期。给一个起点和一批天数,直接给出终点日期;给一个起点和一个整月数,也能通过「日历月」这一格换成天数。做项目排期、试用期到期、贷款首期还款日这类计算时,比在日历上一格一格数可靠。

四是做量纲检查。写报表、看数据字典时经常遇到「这个字段是周还是天」的疑问。把数值丢进来换算一遍,能立刻发现单位用错了:1 个月被当成 4 周(其实是 4.3481 周),100 天被当成 3 个月(其实是 3 个月 8 天),这类错在图表里会放大成明显的偏差。

本页不做这些事:不做闰秒处理,不算工作日与节假日(那是「工作日计算器」的活),不做时区换算,也不做时间戳解析。它只处理「天、周、月、年」这四个时间长度单位之间的折算。

原理:先统一折成天数,再按四种月长分流

调用的函数与算法。这个天周计算器不用任何天文库,核心只有三样:JavaScript 的 Date 构造器(按本地日历建日期)、一个自定义的月末夹取函数 addMonthsClamp()、以及一个逐月递减的循环——while (diffDays(锚点, addMonthsClamp(锚点, k + 1)) <= 天数) k++,把 k 推到「再加一个月就超过总天数」为止,剩下的就是余天数。日差用 Math.round((后 − 前) / 86400000) 计算,取整是为了吸收夏令时造成的 23/25 小时偏差。

为什么用月末夹取,而不是直接加月。JavaScript 的 setMonth() 是溢出式的:1 月 31 日加一个月会得到 3 月 3 日(因为 2 月 31 日不存在,就往后溢出)。这和大多数人对「一个月后」的直觉不符。本页先把目标月的 1 号建出来,查清这个月有多少天,再取 Math.min(原日号, 该月天数),于是 1 月 31 日加一个月得到 2 月 28 日(闰年是 29 日),1 月 31 日加三个月得到 4 月 30 日。差异是实打实的:直接加月给 3 月 3 日,夹取给 2 月 28 日,整整差了三天。

五个常数分别是怎么来的。30 天制月取整数 30,来自会计与债券计息惯例:一年按 360 天、一月按 30 天。公历平均月取 365.2425 ÷ 12 = 30.436875 天,其中 365.2425 来自格里高利历的闰年规则——每 400 年有 97 个闰年,共 400 × 365 + 97 = 146097 天,除以 400 就是 365.2425。朔望月取 29.530588853 天,也就是 29 天 12 小时 44 分 3 秒,这是月相从新月到下一次新月的时间间隔,属于天文常数,和公历的月份没有任何对应关系。年长则给两个:365 是平年天数,365.2425 是格里高利平均年长。

遵循的标准。周的长度依据 ISO 8601:1 周恒为 7 天,周一是一周的第一天,且「第 1 周」定义为包含 1 月 4 日的那一周——这解释了为什么跨年时第 1 周可能落在上一年的 12 月。公历的闰年规则同样来自格里高利历:能被 4 整除的年份是闰年,但整百年必须能被 400 整除才算,所以 2000 年是闰年而 1900 年不是。30 天制月的依据是 30/360 天数计算惯例,债券市场的应计利息至今按它算。

边界与阈值都是具体数字。输入上限 1000000,因为它已经相当于 2739.7 个平年,再大就没有现实意义。JavaScript 的 Date 能表示的范围是 ±8.64×1015 毫秒,换算过来是 ±100000000 天,约 ±273791 年;本页在算出终点日期后检查 isNaN(),一旦超界立刻报错而不是显示 Invalid Date。日差用毫秒除以 86400000,在 100 万天这个量级上误差远小于半毫秒,取整不会出错;1000000 × 86400 = 86400000000 秒远小于 253 = 9007199254740992,所以整数运算不会丢精度。

常见误用纠正三条。第一,把「1 个月」当成 4 周:1 个公历平均月是 30.436875 ÷ 7 = 4.3481 周,按 4 周算,一年会少掉约 6.2 天。第二,把 30 天制月当作日历月:100 天按 30 天制是 3.3333 个月,按日历推是 3 个月 8 天,两者不是同一件事。第三,用 setMonth() 直接做「加 N 个月」的运算,遇到 29、30、31 日的起始日期就会溢出到下个月初,本页的月末夹取就是为了绕开这个坑。

完整示例(默认的 100 天 / 起始日期 2026-03-01)

页面打开时的默认值是 数值 100、单位「天」、起始日期 2026-03-01,结果卡片与对照表第 13 行完全对应,也是这个天周计算器唯一一处「三处咬合」的示例值。同一个 100 天,五套口径算出来是这样:

把这张清单和结果卡片对照着看,会发现一个容易忽略的点:三种「月」的口径给出三个不同的数,差值最大能到 1 天以上。100 天在 30 天制下是 3.3333 个月,在公历平均月下是 3.2855 个月,相差 0.0478 个月,折算回来正好是 0.0478 × 30.436875 ≈ 1.46 天。所以凡是要写进文档的「几个月」,都值得先确认口径。

天数周数月数换算对照表

下表以 2026-03-01 为锚点(与页面默认值一致),把常见天数一次性换算到六种口径。前 12 行直接显示,其余 8 行点「加载更多」。表中的「日历月」列随起始日期变化,改一下起始日期再点「开始换算」,整张表会跟着重算。

天数周 + 天月(30 天制)月(公历平均)月(朔望月)年(365 天制)日历月(自锚点)落点日期
10 周 1 天0.0330.0330.0340.0030 个月 1 天2026-03-02
20 周 2 天0.0670.0660.0680.0050 个月 2 天2026-03-03
30 周 3 天0.1000.0990.1020.0080 个月 3 天2026-03-04
71 周 0 天0.2330.2300.2370.0190 个月 7 天2026-03-08
101 周 3 天0.3330.3290.3390.0270 个月 10 天2026-03-11
142 周 0 天0.4670.4600.4740.0380 个月 14 天2026-03-15
213 周 0 天0.7000.6900.7110.0580 个月 21 天2026-03-22
304 周 2 天1.0000.9861.0160.0820 个月 30 天2026-03-31
314 周 3 天1.0331.0191.0500.0851 个月 0 天2026-04-01
456 周 3 天1.5001.4781.5240.1231 个月 14 天2026-04-15
608 周 4 天2.0001.9712.0320.1641 个月 29 天2026-04-30
9012 周 6 天3.0002.9573.0480.2472 个月 29 天2026-05-30
10014 周 2 天3.3333.2853.3860.2743 个月 8 天2026-06-09
12017 周 1 天4.0003.9434.0640.3293 个月 28 天2026-06-29
18025 周 5 天6.0005.9146.0950.4935 个月 27 天2026-08-28
36552 周 1 天12.16711.99212.3601.00012 个月 0 天2027-03-01
50071 周 3 天16.66716.42716.9321.37016 个月 13 天2027-07-14
1,000142 周 6 天33.33332.85533.8632.74032 个月 24 天2028-11-25
10,0001428 周 4 天333.333328.549338.63227.397328 个月 16 天2053-07-17
1,000,000142857 周 1 天33333.33332854.88433863.1922739.72632854 个月 26 天4764-01-27

从表里能读出三个规律。第一,30 天制月与公历平均月的差距随天数线性放大:100 天差 0.048 个月,1000 天差 0.478 个月,100 万天差 479.449 个月(约 39.9 年),所以小额场景可以忽略,长期场景绝不能混用。第二,「日历月」的余数会跳变:60 天是 1 个月 29 天,再多一天成 61 天就变成 2 个月 0 天,因为四月只有 30 天,跨过月末就会进位。第三,365 天不恰好等于 12 个日历月,从 2026-03-01 起算的 365 天确实落在 2027-03-01,正好 12 个月,但日历月计数依赖具体起止日期,换一个锚点就可能变成 12 个月零几天。

输入范围、边界与舍入说明

常见问题

100 天到底是 3 个月还是 3.33 个月?

取决于你问的是哪一种月。30 天制月下是 3.3333 个月(会计、债券计息用这套);公历平均月(30.436875 天)下是 3.2855 个月;按日历从 2026-03-01 起算则是 3 个月 8 天。三个数都不算错,错的是不说明口径就写「3 个月」。要写进合同或工期表时,建议直接写「100 天」或「自某日起 3 个月 8 天」。

为什么「日历月」必须填一个起始日期?

因为日历月的长度本身不固定:28、29、30、31 天都有。「3 个月」是 89 天还是 92 天,完全取决于从哪一天开始。不给锚点,这个换算就没有唯一答案。本页把起始日期做成必填,就是为了让「几个月」这个说法始终有一个可复现的基准;换一个起始日期,日历月那一列会整列重算。

1 月 31 日加一个月为什么是 2 月 28 日,不是 3 月 3 日?

因为本页用的是月末夹取。setMonth() 的做法是把日期设成 2 月 31 日,JavaScript 发现这一天不存在就往后溢出,得到 3 月 3 日。本页改成先查 2 月有多少天(平年 28 天),再取「原日号 31」与「28」中的较小值,得到 2 月 28 日。两种做法都能自圆其说,但「3 月 1 日之后只过了一个月却跳到 3 月 3 日」会让多数人意外,所以这里选了夹取。闰年时结果是 2 月 29 日。

30 天制月和公历平均月差多少?什么时候该用哪个?

每差 30.436875 − 30 = 0.436875 天。短期看微不足道,长期会积累:100 天差 1.46 天,1000 天差 14.6 天,100 万天差 479.449 个月约 39.9 年。债券应计利息、银行贷款计息日、部分财务报表按 30/360 惯例用 30 天制月;排期、纪念日、合同自然月用日历月。两者不要混用在同一条计算链里。

朔望月 29.530588853 天和公历的「月」有什么关系?

没有直接关系,它是天文量而不是历法量。朔望月是月相重复一次的周期,精确值是 29 天 12 小时 44 分 3 秒左右,与公历月份长度无关,也不等于农历月(农历月按朔望月定,但通过置闰把一年的平均长度拉回回归年)。本页把它列出来,是想说明「月」至少有三种互不相等的定义,混用会出错。真正的农历换算要用「农历公历转换」那一页。

为什么 1 个月不是 4 周,而是 4.3481 周?

因为 4 周只有 28 天,而一个公历平均月是 30.436875 天。按 4 周算一个月,一年就只有 48 周 = 336 天,比真实的一年少了约 29 天。正确的换算系数是 30.436875 ÷ 7 = 4.3481;反过来说,一年是 365.2425 ÷ 7 = 52.1775 周,也是拿 52 周近似会亏掉一天多的地方。

输入 100 万天会算出什么?会不会溢出?

不会溢出。100 万天等于 33333.333 个 30 天制月,或从 2026-03-01 起 32854 个月 26 天,落点日期是 4764-01-27,仍在 Date 的表示范围内(上限约 ±1 亿天)。真要说风险,是这一行的日历月计算需要循环三万余次,在很老的设备上会有几十毫秒的延迟。上限就设在这里,输入更大的数字会被直接拒绝。

为什么「周 + 天」和「周(小数)」要同时给?

两个用途不同。「14 周 2 天」适合排期和口头表达,不会因为四舍五入产生歧义;「14.2857 周」适合继续参与乘法运算,比如按每周工时算总工时。用整数周去做乘法会丢精度:14 周 2 天如果当成 14 周,84 小时的一周工时下会少算 12 小时。算钱、算工时、算产能时用小数周,写文档、排进度时用整数周加余天。

相关工具