Functional patterns

Reusable approaches for handling time correctly in practice.

Parsing user input Human input is ambiguous and locale-dependent — never trust a lenient parser with it. Your own client ↔ server You control both ends — agree one explicit wire contract and serialize symmetrically. 3rd-party data Trust but verify — validate external timestamps against an expected format and fail loudly. The lowest common denominator A value that crosses N systems lives in the intersection of their type systems — design for the weakest hop, and make the loss explicit. Store vs display Store instants in UTC; convert to the user’s local zone only at display time. Formatting for display Delegate to a locale-aware formatter, always with an explicit zone; never hand-assemble date strings. Recurring events A recurrence names civil times, not instants — store the rule and the zone, and materialize occurrences as late as possible. Your schema is a contract Your database schema is an interface other teams read — clear types and unambiguous names keep ETL jobs and analysts from guessing wrong. Naming time fields Encode the meaning in the name — _at for instants, _on for dates, _local/_utc when the type can’t say it, units for durations. The rules Every “always” and “never” in this guide, distilled into one deep-linkable list — share a rule by its link. Pitfalls & anti-patterns A citable index of the warnings scattered across this guide.