Meeting preview shows the day before the date you picked
The date input holds the right value. The shift only appears when a date-only string is formatted in a time zone west of UTC.
workspacesFound 2026-10-19Full report in Replay QA
What the recording showed
parseDateInput('2026-10-20') is new Date(value), which means UTC midnight. Formatted in America/New_York that is 8 PM on Oct 19, so the preview read ‘lunes, 19 de octubre’ for a meeting on the 20th.
Actual
The preview line reads "Reunión el lunes, 19 de octubre de 2026 a las 09:30" — one day earlier than the selected date 2026-10-20 — and the same one-day shift appears for every date entered (the prefilled 2026-10-19 rendered as "Reunión el domingo, 18 de octubre de 2026 a las 10:00"). The date input and time select correctly hold 2026-10-20 and 09:30, but the preview shows the previous calendar day.
Expected
With the date field set to 2026-10-20 and time 09:30, the live preview line under the form should read "Reunión el martes, 20 de octubre de 2026 a las 09:30" — the same calendar date (Tuesday, October 20, 2026) that the user selected in the date input, so the form gives feedback matching the chosen schedule.
Session replay
Chronology of events

0:08.6The user fills the meeting date field with 2026-10-20 (the form previously held the prefilled date 2026-10-19).
2 evidence probes (PlaywrightSteps, InspectElement)
PlaywrightSteps {"mode":"step-detail","stepNumber":308}
→ Step 308: locator.fill
============================================================
Time: 50901ms
Duration: 19ms
API: locator.fill
Category: command
Params: {"selector":"html:nth-of-type(1) > body:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) > main:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(2) > section:nth-of-type(1) > form:nth-of-type(1) > div:nth-of-type(1) > label:nth-of-type(1) > input:nth-of-type(1)","value":"2026-10-20","strict":true,"timeout":15000}
Stack trace:
at invoke scripts/journey/run-script.bundle.cjs:21828:40
at scripts/journey/run-script.bundle.cjs:21851:62
at recordOperation scripts/journey/run-script.bundle.cjs:87803:30
at scripts/journey/run-script.bundle.cjs:21851:22
Inspector Commands (7):
------------------------------------------------------------
[50904ms, point: 69446970483661523371120521428079285] Runtime.callFunctionOn (id: 1655)
params: {"functionDeclaration":"(utilityScript, ...args) => utilityScript.evaluate(...args)","objectId":"-2036979632787793438.10.2","arguments":[{"objectId":"-2036979632787793438.10.2"},{"value":true},{"value":false},{"value":"(injected, { info, callId }) => {\n const elements = injected.querySelectorAll(info.parsed, document);\n if (callId)\n injected.markTargetElements(new Set(elements), callId);\n const element3 = elements[0];\n let log3 = \"\";\n if (elements.length > 1) {\n …InspectElement {"point":"69446970483673458414536211507974851","element":"input[name=\"date\"]"}
→ Element:18 is `<input class="input" type="date" name="date" required="" value="2026-10-20">`.
Element:18 is rendered by React component Schedule at Point:39:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 103 column 18
No elements are obstructing the center point of this element.
Element:18 has 256.65625px width and 36px height.
The width is set by these rules: 100% (100px)
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 8px right 10px bottom 8px left 10px.
Overflow: hidden.
Distances to its parent element:
- Top overflows parent by 21.00px
- Right is aligned with parent boundary
- Bottom is aligned with parent boundary
- Left is aligned with parent boundary
### Parent Element:19
Element:19 is `<label class="field"></label>`.
Element:19 is rendered by React component Schedule at Point:40:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 101 column 16
Element:19 has 256.65625px width and 57px height.
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 0px right 0px bottom 0px left 0px.
Distances to its parent element:
- Top is aligned with parent boundary
- Right overflows parent by 270.67px
- Bottom overflows parent by 71.00px
- Left is aligned with parent boundary
### Parent Element:15
Element:15 is `<div class="form-grid"></div>`.
Element:15 is rendered by React component Schedule at Point:41:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 100 column 14
Element:15 has 527.328125px width and 1…
0:10.3The user picks 09:30 from the time dropdown (the form previously showed time 10:00).
2 evidence probes (PlaywrightSteps, InspectElement)
PlaywrightSteps {"mode":"step-detail","stepNumber":359}
→ Step 359: locator.selectOption
============================================================
Time: 57172ms
Duration: 15ms
API: locator.selectOption
Category: command
Params: {"selector":"html:nth-of-type(1) > body:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(1) > main:nth-of-type(1) > div:nth-of-type(1) > div:nth-of-type(2) > section:nth-of-type(1) > form:nth-of-type(1) > div:nth-of-type(1) > label:nth-of-type(2) > select:nth-of-type(1)","options":[{"label":"09:30"}],"strict":true,"timeout":15000}
Stack trace:
at invoke scripts/journey/run-script.bundle.cjs:21828:40
at scripts/journey/run-script.bundle.cjs:21851:62
at recordOperation scripts/journey/run-script.bundle.cjs:87803:30
at scripts/journey/run-script.bundle.cjs:21851:22
Inspector Commands (7):
------------------------------------------------------------
[57174ms, point: 78533489986135754479609360358053007] Runtime.callFunctionOn (id: 1837)
params: {"functionDeclaration":"(utilityScript, ...args) => utilityScript.evaluate(...args)","objectId":"-2036979632787793438.10.2","arguments":[{"objectId":"-2036979632787793438.10.2"},{"value":true},{"value":false},{"value":"(injected, { info, callId }) => {\n const elements = injected.querySelectorAll(info.parsed, document);\n if (callId)\n injected.markTargetElements(new Set(elements), callId);\n const element3 = elements[0];\n let log3 = \"\";\n if (elements…InspectElement {"point":"78533489986147145344074876006175901","element":"select[name=\"time\"]"}
→ Element:13 is `<select class="input" name="time"></select>`.
Element:13 is rendered by React component Schedule at Point:34:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 107 column 18
No elements are obstructing the center point of this element.
Element:13 has 256.671875px width and 36px height.
The width is set by these rules: 100% (100px)
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 8px right 10px bottom 8px left 10px.
Distances to its parent element:
- Top overflows parent by 21.00px
- Right is aligned with parent boundary
- Bottom is aligned with parent boundary
- Left is aligned with parent boundary
### Parent Element:14
Element:14 is `<label class="field"></label>`.
Element:14 is rendered by React component Schedule at Point:35:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 105 column 16
Element:14 has 256.671875px width and 57px height.
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 0px right 0px bottom 0px left 0px.
Distances to its parent element:
- Top is aligned with parent boundary
- Right is aligned with parent boundary
- Bottom overflows parent by 71.00px
- Left overflows parent by 270.66px
### Parent Element:15
Element:15 is `<div class="form-grid"></div>`.
Element:15 is rendered by React component Schedule at Point:36:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 100 column 14
Element:15 has 527.328125px width and 128px height.
Margin: top 0px right 0px bottom 0px…
0:11.5The schedule preview under the form shows 'Reunión el lunes, 19 de octubre de 2026 a las 09:30' — Monday, October 19 — while the date input holds 2026-10-20 and the time select holds 09:30. The preview is one day earlier than the selected date.
2 evidence probes (Evaluate, InspectElement)
Evaluate {"point":"78533489986147145344074876006175901","scope":"global","expression":"(() => { const dateEl = document.querySelector('input[name=\"date\"]'); const timeEl = document.querySelector('select[name=\"time\"]'); const preview = document.querySelector('[data-testid=\"schedule-preview\"]'); return { dateValue: dateEl.value, timeValue: timeEl.value, previewText: preview ? preview.textContent : null }; })()"}
→ {
"dateValue": "2026-10-20",
"timeValue": "09:30",
"previewText": "Reunión el lunes, 19 de octubre de 2026 a las 09:30"
}InspectElement {"point":"78533489986147145344074876006175901","element":"[data-testid=\"schedule-preview\"]"}
→ Element:7 is `<p class="preview" data-testid="schedule-preview"></p>`.
Element:7 is rendered by React component Schedule at Point:25:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 127 column 16
No elements are obstructing the center point of this element.
Element:7 has 527.328125px width and 36px height.
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 10px right 12px bottom 10px left 12px.
Distances to its parent element:
- Top overflows parent by 211.00px
- Right is aligned with parent boundary
- Bottom overflows parent by 48.00px
- Left is aligned with parent boundary
### Parent Element:8
Element:8 is `<form class="schedule-form" data-testid="schedule-form"></form>`.
Element:8 is rendered by React component Schedule at Point:26:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 95 column 12
Element:8 has 527.328125px width and 295px height.
Margin: top 0px right 0px bottom 0px left 0px.
Padding: top 0px right 0px bottom 0px left 0px.
Distances to its parent element:
- Top overflows parent by 52.00px
- Right overflows parent by 21.00px
- Bottom overflows parent by 21.00px
- Left overflows parent by 21.00px
### Parent Element:9
Element:9 is `<section class="card"></section>`.
Element:9 is rendered by React component Schedule at Point:27:
Relevant code: http://localhost:3204/src/pages/Schedule.jsx line 90 column 8
Element:9 has 569.328125px width and 368px height.
Margin: top 0px right 0px bottom 0px left 0px.
Padding: t…Steps to reproduce
Verify the starting page
Type a title for the new meeting into the meeting title field
Set the meeting date to a near-future date
Pick a start time from the time dropdown
Pick a duration from the duration dropdown
Before submitting, read the live 'Meeting on …' summary line shown under the form
Root cause
In src/lib/dates.js, parseDateInput(value) returns new Date(value). For the date-only string '2026-10-20', new Date('2026-10-20') constructs a Date at UTC midnight (2026-10-20T00:00:00.000Z). Schedule.jsx line 77 (describe = (dateStr) => formatLongDate(parseDateInput(dateStr), language, timeZone)) then passes that instant to formatLongDate, which formats it with Intl.DateTimeFormat in the workspace timeZone 'America/New_York' (UTC-4 in October). At 2026-10-20T00:00:00Z it is 20:00 on 2026-10-19 in New York, so the preview renders 'lunes, 19 de octubre de 2026' — one day earlier than the selected date. The date-only input value must be parsed as a local (or UTC-timezone) date rather than left at UTC midnight when formatted in a non-UTC timezone.
2 evidence probes (Evaluate, SearchSources)
Evaluate {"point":"78533489986147145344074876006175901","scope":"global","expression":"(() => { const d = new Date('2026-10-20'); const fmt = new Intl.DateTimeFormat('es', { timeZone: 'America/New_York', weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); return { iso: d.toISOString(), formattedNY: fmt.format(d) }; })()"}
→ {
"iso": "2026-10-20T00:00:00.000Z",
"formattedNY": "lunes, 19 de octubre de 2026"
}SearchSources {"pattern":"parseDateInput"}
→ ### http://localhost:3204/src/lib/dates.js
hits | L | code
------|------|------
1 | 1 | export const TIMEZONES = [
| 12 |
| *13 | export function parseDateInput(value) {
4 | 14 | return new Date(value);
### http://localhost:3204/src/pages/Schedule.jsx
hits | L | code
------|------|------
| 4 | import { useWorkspaceSettings } from '../lib/settings.js';
| *5 | import { parseDateInput, formatLongDate, formatShortDate, toDateInputValue } from '../lib/dates.js';
| 6 |
10 | 12 | export default function Schedule() /*<HIT>*/{
| 76 |
4 | *77 | const describe = (dateStr) => formatLongDate(/*<HIT>*/parseDateInput(dateStr), language, timeZone);
| 78 |
0 | 152 | {meetings.map((m) => {
0 | *153 | const day = parseDateInput(m.date);
| 154 | return (Root cause → actual behavior
SearchSources 'parseDateInput' shows the function defined in src/lib/dates.js line 14 as return new Date(value) and that Schedule.jsx line 77 formats it via describe = (dateStr) => formatLongDate(parseDateInput(dateStr), language, timeZone), i.e. the preview's date goes through the UTC-midnight parse and the timezone-aware formatter.
1 evidence probe (SearchSources)
SearchSources {"pattern":"parseDateInput"}
→ ### http://localhost:3204/src/lib/dates.js
hits | L | code
------|------|------
1 | 1 | export const TIMEZONES = [
| 12 |
| *13 | export function parseDateInput(value) {
4 | 14 | return new Date(value);
### http://localhost:3204/src/pages/Schedule.jsx
hits | L | code
------|------|------
| 4 | import { useWorkspaceSettings } from '../lib/settings.js';
| *5 | import { parseDateInput, formatLongDate, formatShortDate, toDateInputValue } from '../lib/dates.js';
| 6 |
10 | 12 | export default function Schedule() /*<HIT>*/{
| 76 |
4 | *77 | const describe = (dateStr) => formatLongDate(/*<HIT>*/parseDateInput(dateStr), language, timeZone);
| 78 |
0 | 152 | {meetings.map((m) => {
0 | *153 | const day = parseDateInput(m.date);
| 154 | return (Evaluating new Date('2026-10-20') in the workspace timezone proves the shift: the string parses to ISO 2026-10-20T00:00:00.000Z and Intl.DateTimeFormat with timeZone 'America/New_York' formats that instant as 'lunes, 19 de octubre de 2026'.
1 evidence probe (Evaluate)
Evaluate {"point":"78533489986147145344074876006175901","scope":"global","expression":"(() => { const d = new Date('2026-10-20'); const fmt = new Intl.DateTimeFormat('es', { timeZone: 'America/New_York', weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); return { iso: d.toISOString(), formattedNY: fmt.format(d) }; })()"}
→ {
"iso": "2026-10-20T00:00:00.000Z",
"formattedNY": "lunes, 19 de octubre de 2026"
}The visible state after the time selection confirms the defect: the date input holds '2026-10-20', the time select holds '09:30', and the rendered [data-testid=schedule-preview] element contains 'Reunión el lunes, 19 de octubre de 2026 a las 09:30' — the one-day-earlier date.
1 evidence probe (Evaluate)
Evaluate {"point":"78533489986147145344074876006175901","scope":"global","expression":"(() => { const dateEl = document.querySelector('input[name=\"date\"]'); const timeEl = document.querySelector('select[name=\"time\"]'); const preview = document.querySelector('[data-testid=\"schedule-preview\"]'); return { dateValue: dateEl.value, timeValue: timeEl.value, previewText: preview ? preview.textContent : null }; })()"}
→ {
"dateValue": "2026-10-20",
"timeValue": "09:30",
"previewText": "Reunión el lunes, 19 de octubre de 2026 a las 09:30"
}Is your app hiding bugs like this?
Replay QA explores every build, records what it finds, and writes the root cause.