期间枚举与周旬季年互切,工作日顺延不内置节假日表,自然月进位月末夹取并告警
period-toolSKILL.md 为准。> **本地运行,零网络、免 API Key、数据不出电脑。** > 四项诚实承诺:① 算不出就说算不出,绝不编造日期;② 高危动作强制人工确认;③ 幂等断点,绝不重复副作用;④ 全程留痕可审计。 # 会计期间工具 日期换算也是"看着不会错、错了就全错"的重灾区: 1 月 31 日 + 1 个月到底是 2 月 28 日还是 3 月 3 日? 周六付款到底顺延到周一还是下周一? 季度止日为什么算成了季度首月月末? 「下个月」这种相对词能不能当起算日? 本包把四类高频换算收在一处,并且**每次都把口径写进校验表**: 起止日、天数、粒度定义全部由同一套 `period_of()` 算出, 保证「期间名 / 起 / 止 / 天数」四列互相对得上,不会出现 「2026 年第 1 季度」却写到 1 月 31 日这种自相矛盾的表。 ## 输入 命令行参数算一笔,或传一张批量表逐行算(`.xlsx` / `.csv`): 一张表只跑一个 `--cmd`,列名自动识别: | 用途 | 可识别列名 | |---|---| | 起始年月 / 起算日 | 起始年月 / 年月 / 月份 / 起算年月 / 期间起始年月 | | 日期 | 日期 / 起始日 / 开始日期 / 起算日 / 开票日期 / 到票日期 / 账期起算日 / 付款日 | | 粒度 | 粒度 / 周期粒度 / 期间粒度 / 周期 / 期间类型 | | 个数 | 个数 / 期间个数 / 生成个数 / 数量 | | 账期天数 | 账期天数 / 天数 / 账期 / 账期(天) | | 账期月数 | 账期月数 / 月数 / 账期(月) / 账期月 | | 节假日 | 节假日 / 假期 / 非工作日 / 法定节假日 / 休假日 | | 编号 | 编号 / 单号 / 项目 / 名称 / 摘要 / 序号 | `--cmd` 四选一:`enum` 期间枚举 / `map` 周旬季年切换 / `workday` 工作日调整 / `maturity` 账期与自然日换算。 **粒度只有 5 个**:月 / 旬 / 季 / 周 / 年。 旬 = 上旬 1-10 日、中旬 11-20 日、下旬 21 日至月末; 周 = ISO 周,周一为首日、周日为末日。 「半月 / 半年 / 双周 / 隔月」**不认**,认不出来就直接拒绝并列出可选项—— 猜成「月」会让半月被当成整月报账,这比不做更危险。 ## 输出四件套 | 文件 | 内容 | |---|---| | `pt_主表.csv` | 换算结果(列随 `--cmd` 变化,附 `_来源文件` / `_原始行号`) | | `pt_异常表.csv` | 不可计算项(原因 + 风险等级 + 原始行号) | | `pt_校验表.csv` | 本次换算口径、节假日声明、夹取告警、拒项统计 | | `fin-log.jsonl` | 处理日志(追加) | ## 用法 ```bash PY="<python 3.8+ 路径>" # 纯标准库,零第三方依赖 "$PY" <skill目录>/scripts/period_tool.py --cmd map --date 2026-09-26 --gran 旬 --execute ``` 四类换算(命令行单笔): ```bash "$PY" period_tool.py --cmd enum --start 2026-01 --gran 月 --n 12 --execute # 连续 12 个会计月 "$PY" period_tool.py --cmd map --date 2026-09-26 --gran 旬 --execute # 这天落在哪个旬 "$PY" period_tool.py --cmd workday --date 2026-09-26 --holiday 2026-10-01 --execute # 付款日顺延 "$PY" period_tool.py --cmd maturity --date 2026-01-31 --months 1 --execute # 自然月进位 "$PY" period_tool.py --cmd maturity --date 2026-09-25 --days 30 --execute # 账期 30 天 ``` 批量表(一列一行,逐行算): ```bash "$PY" period_tool.py 期间换算表.xlsx --cmd enum --execute "$PY" period_tool.py 期间换算表.xlsx --cmd workday --execute "$PY" period_tool.py 期间换算表.xlsx --cmd maturity --execute ``` 常用参数:`--start` 起始年月(2026-01 / 2026年1月 / 202601)/ `--gran` 粒度 / `--n` 生成几个 / `--date` 日期 / `--days` 账期天数 / `--months` 账期月数 / `--holiday` 逗号分隔的节假日(如 `2026-10-01,2026-10-02`) / `--out-dir` 输出目录(默认 `_out`)/ `--operator` 操作人 / `--execute` 真正写盘。 **默认不写盘**——不加 `--execute` 只打印预览,确认无误再真跑。 ## 真实输出样例(实测粘贴) ### 1) 期间枚举(6 行输入 → 23 行期间,`selftest/_out/pt_enum.xlsx`) ``` 方案:pt_enum.xlsx | 换算类型 enum(期间枚举) --- 换算结果(23 行)--- EN-01 第1个 2026年1月 起 2026-01-01 止 2026-01-31 31 天 EN-01 第2个 2026年2月 起 2026-02-01 止 2026-02-28 28 天 EN-01 第3个 2026年3月 起 2026-03-01 止 2026-03-31 31 天 EN-01 第4个 2026年4月 起 2026-04-01 止 2026-04-30 30 天 EN-01 第5个 2026年5月 起 2026-05-01 止 2026-05-31 31 天 EN-01 第6个 2026年6月 起 2026-06-01 止 2026-06-30 30 天 EN-02 第1个 2026年1月上旬 起 2026-01-01 止 2026-01-10 10 天 EN-02 第2个 2026年2月上旬 起 2026-02-01 止 2026-02-10 10 天 EN-02 第3个 2026年3月上旬 起 2026-03-01 止 2026-03-10 10 天 EN-02 第4个 2026年4月上旬 起 2026-04-01 止 2026-04-10 10 天 EN-03 第1个 2026年第1季度 起 2026-01-01 止 2026-03-31 90 天 EN-03 第2个 2026年第2季度 起 2026-04-01 止 2026-06-30 91 天 EN-03 第3个 2026年第3季度 起 2026-07-01 止 2026-09-30 92 天 EN-03 第4个 2026年第4季度 起 2026-10-01 止 2026-12-31 92 天 EN-04 第1个 2026年第1周 起 2025-12-29 止 2026-01-04 7 天 ...(其余 8 行见主表文件) ``` ### 2) 周旬季年切换(同一天按 5 种粒度落位,`pt_map.xlsx`) ``` 方案:pt_map.xlsx | 换算类型 map(周旬季年切换) --- 换算结果(12 行)--- MP-01 2026年9月 起 2026-09-01 止 2026-09-30 30 天 MP-02 2026年9月上旬 起 2026-09-01 止 2026-09-10 10 天 MP-03 2026年9月中旬 起 2026-09-11 止 2026-09-20 10 天 MP-04 2026年9月下旬 起 2026-09-21 止 2026-09-30 10 天 MP-05 2026年第3季度 起 2026-07-01 止 2026-09-30 92 天 MP-06 2026年第39周 起 2026-09-21 止 2026-09-27 7 天 MP-07 2026年 起 2026-01-01 止 2026-12-31 365 天 MP-08 2024年2月 起 2024-02-01 止 2024-02-29 29 天 MP-09 2026年1月上旬 起 2026-01-01 止 2026-01-10 10 天 MP-10 2026年9月 起 2026-09-01 止 2026-09-30 30 天 MP-11 2026年第39周 起 2026-09-21 止 2026-09-27 7 天 MP-12 2026年9月 起 2026-09-01 止 2026-09-30 30 天 ``` ### 3) 工作日调整(`pt_workday.xlsx`) ``` 方案:pt_workday.xlsx | 换算类型 workday(工作日调整) --- 换算结果(7 行)--- WD-01 2026-09-26(周六) → 2026-09-28(周一) 顺延 2 天 WD-02 2026-09-27(周日) → 2026-09-28(周一) 顺延 1 天 WD-03 2026-09-25(周五) → 2026-09-25(周五) WD-04 2026-09-28(周一) → 2026-09-29(周二) 顺延 1 天 WD-05 2026-10-01(周四) → 2026-10-06(周二) 顺延 5 天 WD-06 2026-02-16(周一) → 2026-02-17(周二) 顺延 1 天 WD-07 2026-09-30(周三) → 2026-10-01(周四) 顺延 1 天 --- 异常表:本次未发现不可计算项(0 条)--- 注意:本次未考虑法定节假日,结果可能早于实际假期(本包不内置节假日表,请自行用 --holiday 声明) ``` WD-05 的 10-01 / 10-02 / 10-05 是表内「节假日」列声明的,所以顺延到 10-06; WD-06 的 2026-02-16(春节初一)**没有**声明节假日,因此只按周末规则算出 02-17—— 这正是本包不内置节假日表的结果,未声明就必须自己认这一条。 ### 4) 账期与自然日换算,含 4 条月末夹取告警(`pt_maturity.xlsx`) ``` 方案:pt_maturity.xlsx | 换算类型 maturity(账期/自然日换算) --- 换算结果(8 行)--- MT-01 起算 2026-01-31 1 → 到期 2026-02-28 MT-02 起算 2026-03-01 1 → 到期 2026-04-01 MT-03 起算 2024-01-31 1 → 到期 2024-02-29 MT-04 起算 2026-03-31 3 → 到期 2026-06-30 MT-05 起算 2026-08-31 6 → 到期 2027-02-28 MT-06 起算 2026-09-25 账期30天 → 到期 2026-10-25 MT-07 起算 2026-12-15 账期15天 → 到期 2026-12-30 MT-08 起算 2026-09-01 12 → 到期 2027-09-01 --- 异常表:本次未发现不可计算项(0 条)--- --- 账期口径提醒 --- 「账期 N 天」= 起算日 + N 个 24 小时(不跳周末、不跳节假日) 「1 个自然月」= 按月进位,3 月 1 日 + 1 个自然月 = 4 月 1 日(不是 3 月 31 日) 起算日是当月最后一天时按目标月末夹取:1 月 31 日 + 1 个自然月 = 2 月 28/29 日 [夹取告警] MT-01:2026-01-31 + 1 个自然月 → 2026-02-28,已按目标月末夹取(原 31 日 → 28 日) [夹取告警] MT-03:2024-01-31 + 1 个自然月 → 2024-02-29,已按目标月末夹取(原 31 日 → 29 日) [夹取告警] MT-04:2026-03-31 + 3 个自然月 → 2026-06-30,已按目标月末夹取(原 31 日 → 30 日) [夹取告警] MT-05:2026-08-31 + 6 个自然月 → 2027-02-28,已按目标月末夹取(原 31 日 → 28 日) ``` ## 拒绝权(这些情况一律拒绝,不给替代日期) | 情形 | 实测输出 | |---|---| | 相对时间词当日期 | `【算不出】日期「下个月」解析不出来(认 2026-09-26 / 2026年9月26日 / 20260926)` | | 非法日期(13 月) | `【算不出】日期「2026-13-01」解析不出来` | | 粒度「半月 / 半年 / 双周」 | `【算不出】粒度「半月」认不出来,可选:月 / 旬 / 季 / 周 / 年` | | 粒度缺失 | `【算不出】粒度「」认不出来,可选:月 / 旬 / 季 / 周 / 年` | | 个数 0 / 负数 / 小数 / 缺失 | `【算不出】个数 --n 必须是正整数(当前:0)` | | 天数 ≤ 0 / 负数 | `【算不出】账期天数 0 ≤ 0,本包绝不按 0 或负数算账期` | | 月数 ≤ 0 / 负数 | `【算不出】账期月数 -1 ≤ 0,本包绝不按 0 或负数算账期` | | 天数与月数同时给 | `【算不出】账期天数(--days)与账期月数(--months)同时给了,口径冲突算不出` | | 天数与月数都不给 | `【算不出】账期天数与账期月数都没给,算不出到期日` | | 天数是小数 | `【算不出】账期天数「30.5」不是整数` | | `--cmd` 认不出来 | `【算不出】换算类型 --cmd 认不出来或缺失(当前:乱写),可选:enum 期间枚举 / map 周旬季年切换 / ...` | | 节假日写错日期 | `【算不出】节假日「下周一」解析不出来(认 2026-10-01 这样的日期)` | 以上全部为 `退出码=2`,且**无一行 Traceback**(15 条命令行拒绝 + 5 张坏数据表逐行拒绝均实测通过)。 批量表里被拒的行进入 `pt_异常表.csv`,带编号、原因、风险等级、原始行号,绝不静默丢弃。 ## 关键设计(容易踩的坑) 1. **期间名 / 起 / 止 / 天数由同一个函数算出**:枚举时不再手工拼止日, 全部走 `period_of()`,避免出现「2026 年第 1 季度」却止于 1 月 31 日的错表。 2. **「1 个自然月」按自然月进位,不是 30 天,也不是月末对齐**: 2026-03-01 + 1 个自然月 = 2026-04-01(不是 3 月 31 日); 2026-01-31 + 1 个自然月 = 2026-02-28/29(目标月不足时夹取,并逐条告警)。 「账期 30 天」则是起算日 + 30 个自然日,两者不可混用——所以本包**同时给** `--days` 和 `--months`, 给了两个反而拒绝,逼你先想清楚是哪一种口径。 3. **不内置中国法定节假日表**。内置就会过期,而且过期了还装作没过期更骗人。 法定节假日必须由 `--holiday`(或表内「节假日」列)显式声明; 没声明时本包在终端明说「本次未考虑法定节假日,结果可能早于实际假期」, 并把这句话写进 `pt_校验表.csv` 的「节假日声明」一行。 4. **工作日只顺延一次到下一个工作日**,不顺延整周: 2026-09-26(周六)→ 2026-09-28(周一);若 10-01 是节假日则继续往后顺延(WD-05 → 10-06)。 5. **旬一律锚定月初**:起始 2026-01 配粒度「旬」,生成的是 1 月上旬 / 2 月上旬 / …, 不会从「本月剩下的日子」起算。 6. **日期写法认这些**:2026-09-26 / 2026/09/26(斜杠)/ 2026年9月26日 / 20260926 / 2026-09 / 2026年1月 / 202601 / Excel 日期序列号。 「下个月 / 昨天 / 下周三」这类相对词一律拒绝——它们的答案取决于运行当天,不可复现。 7. **本包只算日期,不管账期 contain 的付款审批流程**,也不校验节假日的真实性。 ## 人工复核(必读) - 夹取结果请人工确认是否符合本单位惯例:1 月 31 日 + 1 个自然月, 行业惯例有的落到 2 月最后一天,有的要求回退到约定日——本包只保证"目标月最后一天",不替你选惯例 - 法定节假日务必自己声明。本包没内置表,没声明就等于只按周末算, 遇到跨春节、跨国庆的付款日会明显偏早 - 「账期 N 天」按自然日计算,不跳周末也不跳节假日;若合同约定"工作日到账"口径, 请改用 `workday` 先顺延再算 - 周粒度按 ISO 周(周一为首日),跨年周(如 2025-12-29 ~ 2026-01-04 属 2026 年第 1 周) 与部分企业"自然周(周日至周六)"口径不同,请与内部模板核对 - 结果仅供财务复核,入账 / 申报 / 付款的最终日期需人工确认 ## 相邻路线转交 | 用户要做的事 | 转交给 | |---|---| | 增值税及各税种应纳额计算 | `tax-amount-calc` | | 应收账款账龄账期分析 | `ar-aging` | | 应付账款付款排期与到期提醒 | `ap-payment-schedule` | | 到期票据提醒 | `bill-due-remind` | | 期间损益结转、期末结转检查 | `period-end-carry` / `month-end-close-check` | | 报表期间数取数、跨期数据归集 | `financial-statement-build` | | 金额大写 / 价税分离 / 尾差分摊 | `finance-number-tool` | ## 可直接复制的说法 ```text 帮我算会计期间:给我连续 12 个会计月,起始 2026 年 1 月, 每个期间的起止日和天数都要有。 这一天属于哪个期间就按粒度算:月 / 旬 / 季 / 周 / 年旬按 1-10、11-20、21 到月末, 周按周一到周日。我没有「半月」「半年」这个粒度,别替我猜。 付款日如果落在周末或节假日,顺延到下一个工作日; 法定节假日我不给你表,你自己告诉我哪几天,没告诉你的我就只按周末算。 账期换算先说清楚是哪种: 「账期 30 天」就是起算日 + 30 个自然日; 「1 个月」是自然月进位,1 月 31 日 + 1 个月 = 2 月 28/29 日, 按目标月末夹取的,请把夹取的地方单独列出来给我看。 日期写成 2026-09-26 这种,别用「下个月」, 要是不认就直说算不出,不要按今天替我猜一个。 ``` ## 做完怎么算完成 - [ ] 期间名 / 起 / 止 / 天数四列已逐行互相对得上(季度止日不是季度首月月末) - [ ] 夹取的行已逐条确认符合本单位惯例(1 月 31 日 + 1 个月落点) - [ ] 涉及付款 / 到期的,法定节假日已用 `--holiday` 或表内「节假日」列声明 - [ ] 「账期 N 天」与「账期 N 个自然月」没有被混用(两列只填其一) - [ ] 异常表逐条已追查,无「未说明原因的缺失」 - [ ] 被拒绝的行确实是因为缺参数 / 日期认不出来 / 天数为 0,不是脚本没跑到 --- 本 Skill 采用 BUSL-1.1 许可(源码可见,可自由使用)。 版权所有 © 2026 律令科技(深圳)有限公司(@lexord-technology)。 本技能由律令科技(深圳)有限公司开发,**财友云(caiyouyun.cn)**发布与展示。 允许个人及企业内部免费使用、复制、修改,包括内部生产环境。 未经书面许可,不得将本 Skill 或其修改版作为商业服务对外销售、转售或提供托管服务。 各版本发布之日起 4 年后自动转为 Apache License 2.0。详见随包 `LICENSE.md`。
增值税/附加/个税/印花税/所得税预缴,附公式与政策依据
金额大写、含税不含税互算、价税分离、尾差分摊、百分比反算
五险一金 + 个税累计预扣预缴 + 实发,支持多地参数表
直线/双倍余额/年数总和/工作量法,生成折旧明细表
按年度-凭证号-附件组织,生成目录清单与完整性校验
按人拆成独立文件,可加密打包,不留明文
无形资产与长期待摊费用摊销明细表
新增/折旧/处置/盘点全生命周期台账
等额本息/等额本金/气球贷,含实际利率与 IRR 校验
多币种折算、期末汇兑损益计算,汇率走内置表或导入
合并查询所有财税技能的运行日志,按时间/技能/级别过滤
银行卡/身份证/税号/账套口令扫描与脱敏报告
SKILL.md 为准。