← Exercises|

One column, three formats

Write17 of 26 · about 9 min

One column, three formats

Northstar's export writes created_at in whichever format the tool that produced the row happened to use: ISO-8601 with a Z, dd/mm/yyyy hh:mm from a spreadsheet round-trip, and bare epoch seconds from a script somebody wrote in 2019.

Sorting that column without normalising it produces an order that looks plausible and is wrong — "04/02/2026 14:30" sorts before "2026-02-03T09:12:00Z" because 0 is less than 2. Nothing errors. Reports are simply wrong by a day or two, forever.

The rule for an ingestion layer: normalise at the boundary, once, and refuse what you cannot parse rather than guessing. A value you cannot read is a quarantine row, not a None that flows downstream.

Example

"2026-02-03T09:12:00Z"   # ISO-8601
"04/02/2026 14:30"       # day/month/year - note the ambiguity with month/day
"1770203400"             # epoch seconds

The middle format is ambiguous by design. Northstar is a UK operation, so 04/02 is 4 February.

Your task

Write normalise(value) returning YYYY-MM-DD for all three formats and None for anything else. Then print each ticket as <id> <date>, and finally the count of rows you could not parse.

Stuck?

Explain it

Why is returning None for an unreadable value better than guessing, even though it means the row is dropped from the report?

Not graded — this is for you.

Where this goes

Deliverable D3 is the adapter this belongs to. Its acceptance criteria require that every row is either stored or quarantined with a reason, and that the two counts reconcile against the input on every run.