日期格式检查器
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)。它是唯一一种不会被读出两种意思的格式。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-A02两位数年份
两位年份必须被猜进某个世纪,而各家工具对这个窗口的划法并不一致 —— 有的把 30-99 当成 19xx,有的用相对今天的滑动窗口。同一个文件明年再导入,得到的日期可能就变了。
修复: 年份写全:2026,不写 26。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-A03不带分隔符的紧凑日期
八位数字不带分隔符,可能是 YYYYMMDD、DDMMYYYY 或 MMDDYYYY。通常想写的是 YYYYMMDD,但另外两种读法同样是合法日期,而值本身没有任何东西说明你要的是哪一种。
修复: 加上分隔符并采用 ISO 顺序:2026-02-01。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-A04只是碰巧不歧义
这个具体的值只能有一种读法,因为其中一段大于 12 —— 但格式本身仍然是有歧义的,所以同一列里的其他行可能正在被静默读错。
修复: 要看的是整列,不只是这一行。对 13 号安全的格式,对 2 号并不安全。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-E01表格日期序列号
该放日期的地方是一个裸数字。表格把日期存成天数计数,导出一列从未设过日期格式的单元格时,写出去的就是这个原始计数 —— 45658,而不是 2025-01-01。
修复: 在表格里把该列设为日期格式(或者用 TEXT(单元格,"yyyy-mm-dd")),然后再导出。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-E02序列号 60 是一个从未存在过的日期
表格软件刻意复刻了 1983 年的一个 bug,把 1900 年当成闰年,于是序列号 60 映射到 1900 年 2 月 29 日 —— 那一天并不存在。因此所有小于 61 的序列号都比朴素公式偏移一天,跨越这条边界的日期运算才会出错。
修复: 把任何小于 61 的序列号都当作可疑,把那些行按文本日期重新导出。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-E03表格有两套纪元
默认纪元从 1899 年 12 月 30 日起算,而老版本 Mac 保存的工作簿从 1904 年 1 月 1 日起算。同一个序列号在两套纪元下相差 1462 天 —— 四年多 —— 而导出的 CSV 里没有任何东西记录用的是哪一套。
修复: 回源工作簿确认纪元,或者直接要一份文本形式的日期。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-U01Unix 时间戳
十位数是从 1970 年起的秒数,十三位是毫秒数。两者都是从数据库或 API 漏进了一个本该放日历日期的字段的时间戳。
修复: 写进 feed 之前先转成 ISO 8601。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-V01不存在的日期
这几段组成的日期并不存在 —— 30 天的月份里出现 31 号,或者非闰年出现 2 月 29 日。公历闰年规则是:四年一闰,百年不闰,四百年再闰。
修复: 检查源值;这通常是差一错误,或者字符串拼接出了问题。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
DATE-V02不是日期
按本工具认识的任何一种约定,都从这个值里读不出日期。
来源: Derived from the calendar itself (the Gregorian leap rule and the number of days in each month) and from the arithmetic of spreadsheet date serial numbers, which our tests verify against three independent fixed points.
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;其余都由日历规则与表格序列号运算推出,我们的测试用三个互相独立的定点对它们做过校验。
关于这些规则。 每一条都有编号、严重级别和通俗解释。每个来源链接都已登记在案,并对线上页面实际复验过,而不是凭印象写上去的. 规则如何编写、测试与保持更新 →