发布日期与 JSON-LD 日期不一致

可见的"发布 / 更新"日期与 JSON-LD 的 `datePublished` / `dateModified` 不一致——这不只是外观 bug。

文章 byline 写 “Published May 17, 2026”。view-source:JSON-LD 里 "datePublished": "2024-03-08"。Rich Results Test 通过(技术上合法),但 SERP 不显示带发布日期的 Article rich result。或者 SERP 显示的日期跟你的 byline 不一致。Google 用 datePublished 判断新鲜度、用 dateModified 在结果里显示 “Updated” 标签。两者跟可见 byline 不一致时,Google 哪个都不信,可能彻底压制 rich result。

本文讲日期为什么会漂移、怎么对齐、以及每次构建都 bump dateModified 的陷阱。

常见原因

按命中率从高到低。

1. datePublished 写死或取 build time

模板用 datePublished: new Date() 在构建时生成 JSON-LD,所有文章都显示今天的日期。或者写死成一个常量。

怎么判断:view-source 多篇文章。如果都共享同一个 datePublished(今天或固定值),就是模板。

2. dateModified 每次部署都更新

最常见的变体:dateModified: new Date().toISOString() 在构建时跑。你每周部署。所有文章看起来都是这周修改的。Google 能检测到这个模式,把日期信号打折。

怎么判断:对比你确定没改过的文章的 dateModified。都匹配最近部署日期就是这个 bug。

3. 时区导致 off-by-one 天

Frontmatter:publishedAt: 2026-05-17。模板:new Date('2026-05-17').toISOString() → UTC-8 用户看到 "2026-05-16T16:00:00Z"。可见 byline 是 “May 17”,JSON-LD 是 “May 16”。

怎么判断:ISO 日期串在 UTC 下的日期跟你时区下 byline 显示的日期不一样。

4. CMS 有两个日期字段、模板只用一个

CMS 有 firstPublishedlastEdited。模板只用 firstPublisheddatePublisheddateModified,或反过来。

怎么判断:看模板的 JSON-LD 生成器。如果 datePublisheddateModified 都从同一个字段取,你永远拿不到正确的 “updated” 日期。

5. 迁移过的文章日期错了

CMS 迁移后,所有 datePublished 都被设成了迁移日期。原始发布日期丢失。

怎么判断:所有文章共享一个 datePublished = 你迁移的那一天。对照 git log 或老 CMS。

6. 可见 byline 读 dateModified、JSON-LD 读 datePublished(或反过来)

byline 写 “Updated May 22”。JSON-LD datePublished 是 May 17。两边各自都对,但读者只看到 “May 22”、Google 读到 “May 17” 当发布日。各自正确,整体不一致。

怎么判断:检查 byline,看它对应哪个 JSON-LD 字段。byline 写 “Published” 就应匹配 datePublished;“Updated” 就匹配 dateModified

最短修复路径

第 1 步:建数据模型

每篇文章源里有两个独立日期:

---
publishedAt: 2024-03-08T00:00:00Z   # 不变;不再改
modifiedAt: 2026-05-22T00:00:00Z    # 只在有意义的编辑时改
---

ISO 8601 带显式时区(Z = UTC)。CMS、模板、byline、JSON-LD 统一一个时区。

第 2 步:修模板的 JSON-LD 生成器

---
const { article } = Astro.props;
const published = new Date(article.publishedAt).toISOString();
const modified = article.modifiedAt
  ? new Date(article.modifiedAt).toISOString()
  : published;  // fallback 回 published;不要回 build time
---
<script type="application/ld+json" set:html={JSON.stringify({
  "@context": "https://schema.org",
  "@type": "Article",
  "datePublished": published,
  "dateModified": modified,
  // ...
})}></script>

绝对不要在构建时 new Date()

第 3 步:byline 对齐

<p class="byline">
  发布 {formatDate(article.publishedAt)}
  {article.modifiedAt && article.modifiedAt > article.publishedAt && (
    <span>• 更新于 {formatDate(article.modifiedAt)}</span>
  )}
</p>

两个都显示,标清楚哪个是哪个。

第 4 步:定”有意义的编辑”规则

团队文档:

  • 错别字 / 小措辞:不 bump modifiedAt
  • 加/删章节、更新数据、修事实错误:bump modifiedAt
  • 当新文重发:改 publishedAtmodifiedAt 保持原样。

防止 modifiedAt 漂移。

第 5 步:从 git 历史回填错误日期

# 每篇文章找首次添加它的 commit
for f in src/content/articles/en/*.mdx; do
  first_commit=$(git log --diff-filter=A --follow --format=%aI -- "$f" | tail -1)
  echo -e "$f\t$first_commit"
done

当前 publishedAt 错误(比如等于迁移日期)的文章,用首 commit 日期回填。

第 6 步:CI 审日期

// scripts/check-dates.mjs
import fs from 'node:fs';
import matter from 'gray-matter';

const errors = [];

for (const file of fs.readdirSync('src/content/articles/en')) {
  const { data } = matter(fs.readFileSync(`src/content/articles/en/${file}`, 'utf8'));
  const p = new Date(data.publishedAt);
  const m = data.modifiedAt ? new Date(data.modifiedAt) : null;

  if (isNaN(p)) errors.push(`Invalid publishedAt: ${file}`);
  if (m && isNaN(m)) errors.push(`Invalid modifiedAt: ${file}`);
  if (m && m < p) errors.push(`modifiedAt before publishedAt: ${file}`);
  if (m && Math.abs(m - p) < 60000) errors.push(`Suspicious: modifiedAt == publishedAt within minute: ${file}`);
}

if (errors.length) { console.error(errors.join('\n')); process.exit(1); }

第 7 步:重新请求收录

Search Console → URL Inspection 对几篇文章触发重抓。1-2 周内 Article rich result 应该重新出现。

哪些情况可能不是你操作错了

JSON-LD 矛盾时 Google 也可能从 URL 路径、正文、外部信号推断日期。你无法完全控制 SERP 显示哪个日期——只能控制你提供什么。

容易误判的情况

每次部署都 bump dateModified 想刷新鲜度。Google 能检测到这个模式(所有文章在同一天反复”修改”)并把日期信号整体打折。别玩这个。

预防建议

  • 永远不要从 build time 设 dateModified,只在真实内容编辑时改。
  • CMS / 模板 / byline / JSON-LD 一致用 UTC(或单一编辑部时区)。
  • CI 校验断言 dateModified >= datePublished,两个都是有效 ISO 8601。
  • 团队文档化”有意义编辑”规则。
  • 回填老文章日期时,用 git history 作为原始发布日的可信源。

FAQ

  • dateModified 能早于 datePublished 吗? 不能——非法,Google 会警告。
  • 修错别字要更新日期吗? 不要——只有改动信息的实质编辑才更新。

相关阅读

标签: #SEO #排查 #排查 #结构化数据 #Schema 日期 #JSON-LD