Accounting, Tax & Bookkeeping// diagnostic

Dates and amounts come out wrong, but only for one client's suppliers

In short

Locale faults hide because they can only damage part of the data: about 36% of dates in a year are ambiguous between day-first and month-first order, and only amounts shaped like separators can flip. A supplier whose every invoice is misread still shows a modest error rate, and the fix belongs on the supplier record.

Key takeaways

  • 132 of 365 dates a year parse to a different valid date under the other convention; the rest cannot flip at all.
  • Sample only the ambiguous cases and group by supplier, because averaging hides a supplier that is always wrong.
  • An amount with one separator and 3 trailing digits cannot be resolved from the string; use the document's own arithmetic.
  • Never infer currency from the glyph; several currencies share one symbol and the code is the only reliable field.
  • Store the raw string beside every parsed value, or correcting the locale fixes the future and leaves history wrong.

A locale fault cannot corrupt everything, and that is precisely why it survives review. Only dates whose day number is 12 or less can be read the other way round, and only amounts shaped a certain way can have their separators misread. Everything else extracts correctly, so the overall error rate stays low while one supplier's entire history is systematically wrong.

The arithmetic makes the point. In a 365-day year, 144 dates have a day number of 12 or less; 12 of those are days where the day equals the month and parse identically either way. That leaves 132 dates — about 36% of the year — that resolve to a different, entirely valid date under the opposite convention. If that supplier is a tenth of the client's volume, a total corruption of their documents shows up as a few percent overall, in the bucket everyone calls acceptable.

Sample the ambiguous cases only, and group by supplier

  1. Pull the last 2 quarters of extracted documents for the client together with the raw source strings, not the parsed values alone. Without the raw string the rest of this is guesswork.
  2. Filter to the ambiguous population: dates where the day number is 12 or less, and amounts that contain both a comma and a period, or exactly 1 separator followed by exactly 3 digits.
  3. Group by supplier. Not by month, not by document type — the fault is a property of who produced the page, and any other grouping averages it away.
  4. For the 3 suppliers with the largest ambiguous population, open 10 source documents each and compare the parsed value against what is printed.
  5. Score per supplier and never blend. A supplier at 0% and a supplier at 100% are not a client at 50%, and only one of them needs anything done about it.

Only the first 12 days of a month can flip

Day-first and month-first conventions divide the world, and neither is signposted on the document. A date printed as 03/04/2026 is 3 April in most of Europe, India and much of the Commonwealth, and 4 March in the United States. Nothing in the string says which, and a parser configured for the wrong one is right about two thirds of the time — enough to look healthy on any dashboard.

The defence is structural rather than clever. Normalise every date to ISO 8601 at the boundary, keep the raw string beside it, and record which convention was applied and why. Where a supplier writes the month in letters, treat that as the strongest evidence you will get and use it to set the supplier's hint. And treat a 2-digit year with the same suspicion: a document dated 06/07/08 has 3 plausible readings and deserves review rather than a default.

In much of the world a comma is a decimal point

Amounts fail more expensively than dates. Where a decimal comma is the convention, 1.234,56 is one thousand two hundred and thirty-four and fifty-six hundredths, and a pipeline that strips periods and treats the comma as a group separator returns something 100 times larger. Some locales use a space or a thin space as the group separator instead, which survives a naive strip and then breaks on the character being a non-breaking space rather than a plain one.

The genuinely unresolvable case is worth naming, because teams spend weeks trying to be clever about it. An amount with exactly 1 separator and exactly 3 digits after it — 1,234 or 1.234 — carries no information about which convention produced it, and the difference between the 2 readings is a factor of 1,000. No parser resolves that from the string. Two things do: the supplier's known locale, and the document's own arithmetic.

An invoice carries its own checksum. Line items sum to a net, tax is a rate applied to that net, and net plus tax equals the total — which is enough to decide what a separator meant.

That second route is the durable one. Parse the ambiguous amount both ways, test each reading against the document's internal consistency, and accept the reading that makes the page add up. Where neither reading balances, emit nothing and route the document to a person, which is the same refusal discipline as a statement-to-transactions pipeline that will not emit an unbalanced result.

Two-digit groups, and one symbol shared by many currencies

  • Indian digit grouping. 12,34,567.89 groups the last 3 digits and then in pairs, so a validator built on groups of 3 rejects a perfectly valid amount or drops the row. Stripping separators happens to give the right value here, which means this fault usually appears at validation and formatting rather than in the number itself.
  • Scale words in the amount. Documents may state 1.5 Cr or 2.75 L, where a lakh is 100,000 and a crore is 10,000,000. These need a multiplier and a unit test, and a pipeline that ignores the suffix understates the figure by 5 or 7 orders of magnitude.
  • A glyph is not a currency. The dollar sign is used by the United States, Canada, Australia, Singapore, Hong Kong, Mexico and others; kr covers the Swedish, Norwegian, Danish and Icelandic krone and króna; Rs and its variants cover India, Pakistan, Sri Lanka and Nepal. Take the currency from an explicit ISO 4217 code on the document or from the supplier record, and refuse rather than infer.
  • Period labels are not dates. A stamp reading FY 2025-26 or AY 2026-27 names a period, and periods differ: the Indian financial year runs April to March with a separate assessment year label, the UK personal tax year begins in April on a fixed day, the Australian financial year runs July to June, and the US federal fiscal year starts in October. Model a period label as its own field type so nothing can coerce it into a transaction date — the same separation that makes wage and withholding forms usable by a preparer.
FaultWhere it can appearWorst case
Day-first against month-firstOnly dates with a day number of 12 or lessThe transaction moves month and lands in the wrong return period
Decimal comma or spaceAmounts with 1 separator and 3 trailing digitsA factor-of-1,000 error that passes every range check on a small invoice
Two-digit groupingAmounts in the Indian grouping styleA valid amount fails validation, or the line is dropped in silence
Shared currency glyphAny document using a symbol rather than a codeThe right number posted in the wrong currency
Period label read as a dateTax forms, statements and covering stampsA year label becomes a transaction date nobody questions
Five locale faults, where each one shows, and what it costs

The hint belongs on the supplier, not on the client and not on the tenant

A global setting is the wrong shape for this problem. One client's ledger legitimately contains a local landlord, a European software vendor and a logistics provider billing in a third convention, and a tenant-level locale forces all 3 through one assumption. What varies is the supplier, so that is where the hint lives: date order, decimal separator, group separator, grouping style and currency code, as explicit fields on the supplier record with a default of unknown.

Unknown has to mean something. Route those documents to review rather than to a guess, propose a hint from confirmed corrections once 5 or so documents agree, and require a person to pin it. That whole design assumes supplier identity is stable, which is its own problem when one supplier arrives under 6 different names — a locale hint attached to 6 fragments of one supplier fixes a sixth of the documents.

Build the review queue around ambiguity rather than around model confidence. A date the parser resolved by hint is a different risk from one that could only be read one way, and marking that distinction lets a reviewer spend their attention where it changes an answer. That is ordinary internal tools and ops work, and it is what turns a locale fault from a recurring surprise into a bounded, replayable correction. This page sits in extraction and classification of source documents, part of accounting and tax software.

Frequently asked questions

Short answers to the follow-ups this page tends to raise.

Why is the date format wrong in extracted invoices for only some suppliers?

Because the fault is a property of the document's origin, not of the pipeline as a whole. A supplier writing dates day-first read by a parser expecting month-first is only wrong on dates where the day number is 12 or less — about 36% of the calendar — so their entire history can be corrupted while the client's overall error rate stays in single digits.

How do you detect a date or amount parsing fault that error rates are hiding?

Sample the ambiguous population instead of a random one. Filter to dates with a day number of 12 or less and amounts containing both a comma and a period, group the results by supplier rather than by month, and check source documents for the suppliers with the largest ambiguous populations. A supplier that is always wrong is invisible in an average and obvious in that slice.

How should a pipeline resolve an amount like 1,234 that could be two values?

Use the document rather than the string. Parse both readings and test each against the invoice's own arithmetic — line items summing to the net, tax as a rate on that net, net plus tax equal to the total — and accept the reading that balances. Where neither balances, refuse to emit a value and route the document to a reviewer, because the two readings differ by a factor of 1,000.

Should the locale setting live on the client or on the supplier?

On the supplier. A single client's ledger routinely contains suppliers from several countries, so a client-level or tenant-level setting forces unlike documents through one assumption. Hold date order, decimal separator, grouping style and currency code on the supplier record, default them to unknown, and require a person to confirm a proposed value before it is applied.

  • document extraction
  • data quality
  • localisation
  • invoices
// shipped work

The work behind this page

Builds from our portfolio that this page draws on.

Read next

Working on something in this space?

Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.

Start the conversation