2026-09-30 · 7 min read
- yaml
- config
- dates
A calendar day in a config file is usually a label, not an instant. YAML 1.1 can still resolve an unquoted 2026-09-30 as a timestamp. The next serializer then prints a date-time, and a time zone can move that instant onto another calendar day.
The safe contract is a string in the file and a string after parsing, unless the application truly wants an instant and documents the zone.
Choose a schema and quote the exceptions
Prefer a YAML 1.2 JSON or core schema when the library allows it, so plain dates stay strings. When a dependency still implements YAML 1.1 timestamps, quote every date, date-time, and version-like token that must not change type.
- Quote date-only values: '2026-09-30'.
- Quote version strings such as '1.10'.
- Pin the parser name and major version.
- Reject a deploy if CI and production use different loaders.
Separate calendar dates from instants
If the value is a civil date with no time, store a string or a date type that has no zone. If the value is an instant, store an explicit offset or Z and test that offset. Midnight invented by a timestamp resolver is not a time the author chose.
Formatting that instant in a zone west of UTC shows the previous date. The bug is visible in the UI and invisible in the YAML, which makes the raw file the wrong place to stop the investigation.
Find the loader that changes the type
Template engines, Kubernetes libraries, and application config stacks can each parse YAML. A value that stays a string in CI can become a timestamp in the service image. Capture the type after each hop: source text, template output, platform object, and application struct.
Go, Python, and Java libraries changed timestamp behavior across major versions. A lockfile bump is enough to reintroduce the conversion. Review YAML parser upgrades the same way you review database migrations.
Test the emitted JSON, not only the source
Use Flashman's YAML/JSON converter to load the file, the JSON formatter to read the result, diff to compare quoted and unquoted forms, the timestamp converter to place midnight in the service zone, and the Markdown editor to record the intended type of each field.
Include a date-only value, a zoned date-time, a quoted date, a version string, and the same document in CI and production loaders. The calendar day in the output should match the calendar day in the source.