A second Search Console error landed on the same /about page that triggered the ProfilePage mainEntity bug. This one is shorter to explain and easier to fix.
Invalid datetime value for dateModified
The value Search Console did not like:
"dateModified": "2026-05-13"
Schema.org accepts both Date and DateTime on the dateModified, dateCreated, and datePublished fields. The schema validator passes the date-only form. The Rich Results Test passes it. Search Console's strict validator emits the error above and marks the rich result ineligible.
If you set those fields by hand in a template, or by pasting today's date in a Markdown frontmatter that flows into JSON-LD, this bug is probably on your site too.
The fix
Convert the value to a full ISO 8601 datetime with timezone offset:
"dateModified": "2026-05-13T00:00:00-06:00"
That is the same calendar date with three additional pieces of information added. A T separator. A time component (here, midnight). A timezone offset (here, Mountain Daylight Time).
Each piece serves a purpose for the strict validator. The T separator says "this is an ISO 8601 datetime, not a date." The time component says "this is the moment within that calendar day." The timezone offset says "this is which clock that moment refers to." Together they make the value unambiguous to a machine that has no other context, which is what Search Console wants.
Why Search Console is stricter than schema.org
Schema.org defines dateModified as accepting either Date or DateTime. The schema validator answers the question "does this value conform to either type?" and passes the date-only form because Date accepts it.
Google Search Console's rich-result validator has a different job. It decides whether the field is unambiguous enough to surface in a search-result feature. A date without a time component is ambiguous about which moment on that day the modification occurred. For some rich-result types where freshness is the ranking signal, the ambiguity matters.
I do not love that two validators give different answers on the same schema, but I do not control that. The pragmatic move is to satisfy the stricter one, because the stricter one is what decides whether the page actually appears as a rich result in search.
Pick the right timezone offset
The timezone offset is the part most people get wrong. The two common patterns I see:
Pattern A: use the local business timezone. If the site is for a business in Idaho, use Mountain Time. Mountain Daylight Time is -06:00. Mountain Standard Time is -07:00. Idaho observes DST so the offset shifts twice a year. Use the offset that applies on the date the field actually represents. A date in May uses -06:00. A date in December uses -07:00.
Pattern B: use UTC. Add a Z suffix instead of an offset: "2026-05-13T00:00:00Z". Some build tooling defaults to UTC because it is unambiguous. Both forms are valid. UTC is fine if you do not care about clock-local interpretation.
Mountain Time offsets:
- Mountain Daylight Time, March to November:
-06:00 - Mountain Standard Time, November to March:
-07:00 - Arizona (no DST):
-07:00year round
Other common US offsets:
- Pacific:
-07:00summer,-08:00winter - Central:
-05:00summer,-06:00winter - Eastern:
-04:00summer,-05:00winter - Hawaii (no DST):
-10:00year round
If you do not care which clock the time refers to (and for dateModified you usually do not, because Google reads it for freshness ranking and the date component is what matters), midnight in any consistent offset is fine. Pick one and use it everywhere.
Where the date-only bug usually originates
Three common sources, in order of frequency:
Markdown frontmatter. Eleventy, Hugo, Astro, Jekyll, and Next.js MDX all use date: 2026-05-13 in YAML frontmatter for blog posts. When that value flows into a JSON-LD datePublished field through a template, the YAML parser hands it back as a date object that serializes to "2026-05-13". Fix it at the template level by converting to ISO 8601 datetime on output.
new Date().toISOString().slice(0,10). A common one-liner for "today's date" in JavaScript build scripts. The .slice(0,10) chops the time component off, which is exactly what you do not want. Use new Date().toISOString() without the slice for a UTC datetime, or use a date library that emits the local-offset form.
Hand-edited dates in HTML. Static-site authors sometimes paste today's date into a JSON-LD block by hand. Without the time component because typing it is tedious. This is where the date-drift problem lives: hand-written dates fall out of sync with the actual content and stop being useful as freshness signals. Build-time injection is the structural fix.
Build-time injection in Nunjucks (Eleventy)
The cleanest pattern is a single helper that emits the current build time as a properly formatted ISO datetime. In Eleventy's .eleventy.js:
const { DateTime } = require('luxon');
module.exports = (config) => {
config.addShortcode('buildIso', () => {
return DateTime.now().setZone('America/Denver').toISO({suppressMilliseconds: true});
});
};
Then in the layout:
"dateModified": "{% buildIso %}"
Result on every deploy:
"dateModified": "2026-05-16T14:23:00-06:00"
The Luxon library handles DST transitions correctly. The shortcode fires at build time, so the value reflects the moment the page was rendered.
For Hugo, the equivalent template helper:
{{ now.Format "2006-01-02T15:04:05-07:00" }}
For Next.js (server-side render):
const dateModified = new Date().toISOString();
For Astro:
const dateModified = new Date().toISOString();
All emit ISO 8601 datetimes that satisfy Search Console.
What about hand-written canonical dates
Some pages have a real, manually-curated datePublished that should not be the build time. A blog post that was published last March should have datePublished: "2026-03-12" in frontmatter and stay there forever, separately from the build-time dateModified.
Pattern for that case. Keep the frontmatter date-only. Convert it to ISO 8601 datetime in the template:
"datePublished": "{{ page.date | date('yyyy-MM-dd\'T\'HH:mm:ssXXX') }}"
If your template engine does not have a date-format filter, write one that wraps Luxon or date-fns. Hand-rolling the format string is fragile because of DST.
The shape of the rule. Frontmatter holds the canonical date. The template renders it as a full ISO 8601 datetime at build time. The strict validator gets what it wants. The freshness signal stays accurate.
Combine with the build-time dateModified
The standard convention I use on sites with editorial content:
datePublished: derived from the frontmatterdate, formatted as ISO 8601 datetime with timezone, at template render timedateModified: emitted by a{% buildIso %}shortcode that fires on every build
The build pipeline runs on every deploy, so dateModified reflects the actual last-modified moment for the page's source. The datePublished reflects the original publication. Both are ISO 8601 datetime so Search Console is happy.
For sites where the content rarely changes and you want dateModified to track only meaningful edits, store an explicit dateModifiedIso in the page frontmatter and reformat it through the same template filter. That gives you control over when the freshness signal moves.
Why this pairs with the ProfilePage bug
The two errors landed in Search Console on the same day for the same /about page because they both descend from the same pattern. A template author put the canonical bio on the homepage, then built a thin ProfilePage on /about that referenced the Person by @id and added a couple of editorial dates. The schema validator passed. The Rich Results Test passed. Search Console flagged both fields on the next crawl, three days later.
Both are strict-validator errors. Both can be fixed at the template level in one PR. Together they fix the ProfilePage rich result for the /about page and restore the page's eligibility to appear with the dedicated profile UI in search.
How to find every date-only field
Walk every JSON-LD block in your rendered HTML and grep every node for fields ending in Created, Modified, or Published. Any value matching ^\d{4}-\d{2}-\d{2}$ (exactly ten characters, year-month-day, no T separator) is what Search Console flags.
In DevTools:
const blocks = [...document.querySelectorAll('script[type="application/ld+json"]')];
const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
const FIELDS = ['dateCreated', 'dateModified', 'datePublished'];
const hits = [];
function walk(n) {
if (!n || typeof n !== 'object') return;
if (Array.isArray(n)) return n.forEach(walk);
FIELDS.forEach(f => {
if (typeof n[f] === 'string' && DATE_ONLY.test(n[f])) {
hits.push({type: n['@type'], field: f, value: n[f]});
}
});
Object.values(n).forEach(v => { if (v && typeof v === 'object') walk(v); });
}
blocks.forEach(b => {
try { walk(JSON.parse(b.textContent)); } catch (e) {}
});
console.log(hits);
Anything in the hits array is what to fix.
Related reading
- The companion ProfilePage mainEntity post — the other Search Console strict-validator error that shipped on the same page
- Nine AI Mode entity-binding bugs that pass every schema validator — the predecessor post on validator-blind binding bugs
- Why Sitemap lastmod truthfulness matters more than you think — the date-drift problem in a different form
- Schema validator vs Rich Results vs Search Console — three validators, three different verdicts — broader context on validator divergence
- The Mega Analyzer — where this detector lives in the audit chain
Fact-check notes and sources
- Schema.org Date and DateTime spec: schema.org/Date, schema.org/DateTime
- Schema.org
dateModifieddefinition: schema.org/dateModified - ISO 8601:2019 specification (paid, but the Wikipedia summary is accurate): en.wikipedia.org/wiki/ISO_8601
- Google Search Console rich-result error reference: support.google.com/webmasters/answer/7552505
- Luxon date library docs (for build-time helpers): moment.github.io/luxon
- Mountain Time UTC offsets (DST schedule): www.timeanddate.com/time/zone/usa/denver
This post is informational, not legal or SEO-consulting advice. The Search Console error described here is documented in Google's rich-results help center and reproducible against the live validator.