CodeRigor

FREE LESSON

Dates, currency and finite numbers

Apply strict calendar and currency grammars, preserve exact integer cents and reject non-finite numeric observations.

A date, a currency amount and a scientific measurement are all values, but they need different grammars. A permissive constructor can accept spellings your feed never promised. Guessing a locale can turn 03/04 into either March 4 or April 3. Dropping punctuation can turn malformed currency into a plausible amount. Write down the allowed spelling, range and precision before converting it.

The build has three independent parsers. Each raises ValueError for rejected input; none uses zero as an error sentinel. Boundary whitespace is stripped from text, but internal notation must match its own policy. This lets a caller decide whether to reject the whole document, record a row error or ask for correction. A parser should not secretly choose that downstream workflow.

Grammar, then domain validation
start / 2
Successful conversion is only one part of a valid field.
Grammar, then domain validation
Successful conversion is only one part of a valid field.

Dates need both syntax and a calendar

date.fromisoformat accepts several ISO forms, including compact dates. A feed requiring exactly YYYY-MM-DD needs an ASCII shape check before that constructor. The constructor then rejects impossible days such as 2023-02-29. A regex alone cannot establish leap-year validity. Return the canonical date.isoformat() string so downstream comparisons have a consistent spelling.

A calendar date is not an instant. This lesson does not assign midnight, a time zone or a UTC offset to it. Event timestamps require separate rules for offsets, ambiguous local times and normalization. Do not pretend a date-only field carries that information.

Python
from datetime import date
from decimal import Decimal

print(date.fromisoformat('2024-02-29').isoformat())
print(int(Decimal('0.29') * 100))
print(int(float('0.29') * 100))

The exact decimal path returns 29 cents; the float path can truncate a binary approximation to 28. Construct Decimal from text, not from an already-rounded float. The build uses a local precision sized for its bounded input so a lower ambient precision does not round away cents.

Exact cents and finite measurements
start / 2
A valid zero differs from missing text and from a non-finite number.
Exact cents and finite measurements
A valid zero differs from missing text and from a non-finite number.

Currency punctuation is a grammar

The exercise accepts USD-style comma groups, optional dollar signs, an optional leading minus and at most two fractional digits. -$1,000.20 is valid; $-1, 1,00, .50 and 1.001 are rejected. Removing all commas without checking their groups would repair an unknown notation without evidence. Supporting other currencies, locale conventions, exchange rates or accounting rounding requires new policy rather than another broad replacement.

The general measurement parser deliberately uses Python's float grammar and then requires math.isfinite. NaN and infinities are valid float objects, yet invalid observations here. An enormous exponent can produce infinity without a parse error. Also reject booleans before conversion, and handle conversion overflow from a huge integer.

In practice, test a leap day in a century year, a compact date, negative five cents, malformed comma grouping, a zero amount and a non-finite exponent. Explain why strict grammar, exact arithmetic and finiteness are three different checks.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

Review 57:13–1:14:05 for the file-to-record boundary. This lesson and the official date/Decimal/math documentation teach the stricter value parsers; the lecture does not claim to teach financial or time-zone rules.