日期格式检查器
01/02/2026 在世界大多数地方是 2 月 1 日,在美国是 1 月 2 日。同样的字符,差了一个月,而没有任何导入器会提醒你。粘一个日期进来,看它到底有几种读法 —— 附带星期几,那通常就是你分辨「哪个才是我的」的办法。
🔒 你的数据不会离开浏览器。
为什么日期列比它看上去危险
日期没有自我描述的格式。03/04/2026 在两种不同约定下都是完全合法的日期,所以没有解析器会拒收它,也没有谁会告诉你它选了哪一种。这种失败是无声的,它只影响两个数字恰好都不大于十二的那些行,而且能扛过每一轮肉眼检查 —— 这正是它能进到生产环境的原因。
唯一一种不会被读出两种意思的格式是 ISO 8601:2026-02-01。年在最前,按重要性从大到小。它按纯文本排序也是正确顺序 —— 这是其他任何格式都不给你的白送好处。
那个其实是日期的数字
表格把日期存成天数计数。导出一列从未设过日期格式的单元格,你拿到的就是这个原始计数 —— 45658 而不是一个日期。这个计数是精确且可逆的,所以本工具会把它解回来:
1→ 1900-01-0160→ 1900 年 2 月 29 日 —— 一个从来不存在的日子61→ 1900-03-0125569→ 1970-01-0145658→ 2025-01-01
60 那里的断口不是本工具的错。表格软件为了兼容一个更老的产品,刻意复刻了 1983 年的一个 bug,把 1900 年当成闰年。于是序列号 60 指向 1900 年 2 月 29 日 —— 一个不存在的日期,而所有小于 61 的序列号都比朴素公式偏移一天。跨越这条边界的日期运算会差一天。
还有第二个陷阱:老版本 Mac 保存的工作簿从 1904 年 1 月 1 日起算,同一个序列号因此相差 1462 天 —— 四年多。导出的 CSV 里没有任何东西记录这个数出自哪套纪元,所以本工具给出默认读法,并把另一种点名说出来,而不是假装只有一种。
不带时区的时间不是一个时刻
2026-02-01T00:00:00 是某地的午夜,但这串字符没说是哪里。Google Merchant Center 并不是简单地回落到 UTC:文本与 XML feed 用的是目标国家的默认时区,而 API 用 UTC。所以同一个字符串,提交方式不同就意味着两个不同的时刻,促销窗口两端各会因此挪动最多一天。
Merchant Center 要求区间写成 start/end —— 例如 2026-02-01T00:00:00-0800/2026-02-28T23:59:59-0800。结束早于开始的区间会被照收,然后干脆不跑,所以本工具连方向也一起查。
本工具执行的全部检查(14 条规则)
DATE-A01日月顺序有歧义
两个数字都不大于 12,所以这个值在两种约定下都是合法日期。“01/02/2026” 在世界大多数地方是 2 月 1 日,在美国是 1 月 2 日 —— 差了一个月,而任何解析器都不会报错。
修复: 把这一列按 ISO 8601 重新导出(2026-02-01)。它是唯一一种不会被读出两种意思的格式。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-A02两位数年份
两位年份必须被猜进某个世纪,而各家工具对这个窗口的划法并不一致 —— 有的把 30-99 当成 19xx,有的用相对今天的滑动窗口。同一个文件明年再导入,得到的日期可能就变了。
修复: 年份写全:2026,不写 26。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-A03不带分隔符的紧凑日期
八位数字不带分隔符,可能是 YYYYMMDD、DDMMYYYY 或 MMDDYYYY。通常想写的是 YYYYMMDD,但另外两种读法同样是合法日期,而值本身没有任何东西说明你要的是哪一种。
修复: 加上分隔符并采用 ISO 顺序:2026-02-01。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-A04只是碰巧不歧义
这个具体的值只能有一种读法,因为其中一段大于 12 —— 但格式本身仍然是有歧义的,所以同一列里的其他行可能正在被静默读错。
修复: 要看的是整列,不只是这一行。对 13 号安全的格式,对 2 号并不安全。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-E01表格日期序列号
该放日期的地方是一个裸数字。表格把日期存成天数计数,导出一列从未设过日期格式的单元格时,写出去的就是这个原始计数 —— 45658,而不是 2025-01-01。
修复: 在表格里把该列设为日期格式(或者用 TEXT(单元格,"yyyy-mm-dd")),然后再导出。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-E02序列号 60 是一个从未存在过的日期
表格软件刻意复刻了 1983 年的一个 bug,把 1900 年当成闰年,于是序列号 60 映射到 1900 年 2 月 29 日 —— 那一天并不存在。因此所有小于 61 的序列号都比朴素公式偏移一天,跨越这条边界的日期运算才会出错。
修复: 把任何小于 61 的序列号都当作可疑,把那些行按文本日期重新导出。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-E03表格有两套纪元
默认纪元从 1899 年 12 月 30 日起算,而老版本 Mac 保存的工作簿从 1904 年 1 月 1 日起算。同一个序列号在两套纪元下相差 1462 天 —— 四年多 —— 而导出的 CSV 里没有任何东西记录用的是哪一套。
修复: 回源工作簿确认纪元,或者直接要一份文本形式的日期。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-U01Unix 时间戳
十位数是从 1970 年起的秒数,十三位是毫秒数。两者都是从数据库或 API 漏进了一个本该放日历日期的字段的时间戳。
修复: 写进 feed 之前先转成 ISO 8601。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-V01不存在的日期
这几段组成的日期并不存在 —— 30 天的月份里出现 31 号,或者非闰年出现 2 月 29 日。公历闰年规则是:四年一闰,百年不闰,四百年再闰。
修复: 检查源值;这通常是差一错误,或者字符串拼接出了问题。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-V02不是日期
按本工具认识的任何一种约定,都从这个值里读不出日期。
来源: 依据的是历法本身(格里高利历的闰年规则与每月天数),以及电子表格日期序列号的算术;我们的测试用三个互不依赖的定点验证它。
DATE-T01没有时区
不带时区的时间戳不是一个时刻 —— 它是「读它的人假定的那个时区里的」一个时刻。Google Merchant Center 并不是简单地假定 UTC:文本与 XML feed 用的是目标国家的默认时区,而 API 用 UTC。所以同一个字符串,提交方式不同就意味着两个不同的时刻,促销窗口两端各会因此挪动最多一天。
修复: 显式写上偏移量,例如 2026-02-01T00:00:00-0800。
DATE-T02ISO 8601 —— 无歧义
年-月-日,按重要性从大到小排列。它只有一种读法,按纯文本排序就是正确顺序,而且这正是 feed 规范要求的写法。
DATE-G01日期区间
区间是用斜杠分开的起止两段:start/end。Merchant Center 的促销价生效日期用的就是这个写法,两半各自遵守同样的日期与时间规则。
DATE-G02区间的结束早于开始
区间的结束时间早于它的开始时间,所以这个窗口永远不会打开。这样提交的促销根本不会跑,而且没有任何环节会拒绝这一行。
修复: 把两半对调,或者检查其中一半是不是把日月顺序写反了。
月份名称只识别英文写法。时区与区间这两条规则依据 Google Merchant Center — Format date and time;其余都由日历规则与表格序列号运算推出,我们的测试用三个互相独立的定点对它们做过校验。
关于这些规则。 每一条都有编号、严重级别和通俗解释。每个来源链接都已登记在案,并对线上页面实际复验过,而不是凭印象写上去的. 规则如何编写、测试与保持更新 →