DateHelper: accept ISO-8601 timestamps with optional fractional seconds - #98
Merged
Conversation
…connectivity problems
Dev/networ error messages
parseServerInstant and parseNaiveDateTime documented that any explicit
ISO-8601 offset parses, but SERVER_PATTERN_FULL_OFFSET demands exactly
six fractional digits — so Laravel/Carbon toIso8601String() output
("2026-07-02T12:09:58+00:00", no fraction) fell through every parser
and silently returned null. Caught in the field on Accelerate: the user's
onboarding_completed_at/created_at arrived as null through
NullableZonedDateTimeSerializer while every other field parsed fine.
Add purely additive fallbacks so behaviour matches the docs:
- parseServerInstant: try DateTimeFormatter.ISO_OFFSET_DATE_TIME
(fractional seconds optional, 0-9 digits) after the strict pattern,
before the Carbon short form.
- parseNaiveDateTimeInternal: try ISO_LOCAL_DATE_TIME after
NAIVE_PATTERN_FULL, and ISO_OFFSET_DATE_TIME after
SERVER_PATTERN_FULL_OFFSET.
The strict parsers stay first, so anything that parsed before still
parses identically — the existing legacy-behaviour suites pass
unchanged. New DateHelperIsoToleranceTest covers the Carbon form,
fraction-less Z, millisecond precision, non-UTC offsets, and the
still-working strict forms.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jakeeilbeck
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
parseServerInstant/parseNaiveDateTimedocument that any explicit ISO-8601 offset parses — butSERVER_PATTERN_FULL_OFFSETdemands exactly six fractional digits, so Laravel/CarbontoIso8601String()output (2026-07-02T12:09:58+00:00, no fraction) fell through every parser and returned null.Caught in the field on Accelerate today: a real device login stored the user fine, but
onboarding_completed_at/created_atarrived as null throughNullableZonedDateTimeSerializer— silently, since the fields are nullable:The consuming backend has ~32 date fields emitting this format, and
toIso8601String()is common across Laravel backends generally — hence fixing the parser once here rather than chasing every backend.Fix — purely additive fallbacks
The strict parsers stay first, so any input that parsed before still parses identically (the legacy-behaviour suites pass unchanged). Only previously-failing inputs reach the new steps:
parseServerInstant: after the strict pattern, tryDateTimeFormatter.ISO_OFFSET_DATE_TIME(fractional seconds optional, 0–9 digits;Z/±HH:MMoffsets) before the Carbon short-format fallback.parseNaiveDateTimeInternal: tryISO_LOCAL_DATE_TIMEafterNAIVE_PATTERN_FULL, andISO_OFFSET_DATE_TIMEafterSERVER_PATTERN_FULL_OFFSET.Tests
New
DateHelperIsoToleranceTest(10 cases): the literal field-failure string, fraction-lessZ, millisecond precision, non-UTC offsets, still-working strict forms, garbage rejection, and the naive-chain equivalents. FullDateHelperUtil+DateHelperUtil-Serializationsuites green.Also included
🤖 Generated with Claude Code