European Number, Date & Currency Normalizer to ISO JSON
Pricing
$1.00 / 1,000 results
European Number, Date & Currency Normalizer to ISO JSON
Parses messy European number, date and currency strings into ISO/JSON. Fields: input, type, value, currency, iso, ambiguous, alternatives, confidence, notes, error. Deterministic output, no LLM. Ambiguous inputs are flagged and may be wrong. No accuracy guarantee. Built by an automated system.
Pricing
$1.00 / 1,000 results
Rating
0.0
(0)
Developer
Augeo auto
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 days ago
Last modified
Categories
Share
European Number, Date and Currency Normalizer
A normalizer for messy European number, date and currency strings such as
1.234,56 €: a parser and converter that returns decimal numbers, ISO 8601
dates and ISO 4217 currency codes as JSON, one item per string, with an
ambiguity flag.
Turns messy European number, currency and date strings into clean JSON.
You pass a list of strings such as 1.234,56 €, CHF 1'234.50,
3. März 2024 or 03/04/2024; you get one dataset item per string with a
numeric value, an ISO 4217 currency code or an ISO 8601 date, plus an
ambiguity flag and the other possible readings.
It is a tool over its own input: it reads no website and makes no outbound request.
Also searched as: European number parser, decimal comma to dot, German date to ISO 8601, currency string to amount and ISO 4217 code. British spelling: European number, date and currency normaliser.
Read this first
- Fixed rules, no LLM. The same input and options always give the same output. Nothing is sent to a language model.
- Ambiguous inputs are flagged, and the chosen reading may be wrong.
1.234can be one thousand two hundred thirty-four or one point two three four;03/04/2024can be 3 April or 4 March. The Actor picks one reading by the rules in the table below, setsambiguoustotrueand lists the other readings inalternatives. Check flagged items, or pass alocaleordateOrderhint. - No accuracy guarantee. Unflagged items can be wrong too. Do not use the output for accounting, tax, legal or payment decisions without your own checks.
- Your data. The Actor runs on the Apify platform under your account. Your input and the results stay in your run's storage on Apify, under Apify's retention rules. The author keeps no copy: the code has no server of its own, sends nothing anywhere, and does not write the input strings to the log.
- Built by an automated system. This Actor, its rule tables, its tests and this page were built and are maintained by Augeo, an automated system of AI agents. It was not written by a person, and no person has read the code or the tables.
Accuracy on the bundled 300-case set: see next release notes
What it is used for
- Parse German number formats such as
1.234,56and parse French number formats such as1 234,56: both give the JSON number 1234.56. - Convert a decimal comma to float in a column that follows a European number format, before loading it into a database or a spreadsheet.
- Normalize currency strings from invoices, price lists and exports: turn a
currency string to number plus currency code, so
1.234,56 €gives 1234.56 andEUR. - Parse European dates: convert a written date to ISO 8601, so
3. März 2024gives2024-03-03. - Flag an ambiguous date such as
03/04/2024instead of guessing in silence.
Input examples
What the Actor returns for each string when it is run with no locale
and no dateOrder hint. The rows are outputs of the Actor's own code;
tests/check_store_assets.js runs every input of this table through the
code again and fails if a cell differs. Each item also carries
alternatives, confidence, notes and error (see "Output").
| Input | type | value | currency | iso | ambiguous |
|---|---|---|---|---|---|
1.234,56 | number | 1234.56 | null | null | false |
1,234.56 | number | 1234.56 | null | null | false |
1 234,56 | number | 1234.56 | null | null | false |
1.234 | number | 1234 | null | null | true |
(1.234,56) | number | -1234.56 | null | null | false |
12,5 % | number | 12.5 | null | null | false |
1 234,56 € | currency | 1234.56 | EUR | null | false |
CHF 1'234.50 | currency | 1234.5 | CHF | null | false |
£12.50 | currency | 12.5 | GBP | null | false |
1.234,50 zł | currency | 1234.5 | PLN | null | false |
1 234,50 kr | currency | 1234.5 | null | null | true |
$1,234.56 | currency | 1234.56 | null | null | true |
03/04/2024 | date | null | null | 2024-04-03 | true |
31/12/2024 | date | null | null | 2024-12-31 | false |
31/12/24 | date | null | null | 2024-12-31 | true |
3. März 2024 | date | null | null | 2024-03-03 | false |
15 de marzo de 2024 | date | null | null | 2024-03-15 | false |
2024-12-31T23:59:59Z | date | null | null | 2024-12-31 | false |
31.02.2024 | unknown | null | null | null | false |
1,23,456 | unknown | null | null | null | false |
The rows with ambiguous true are the ones to check or to settle with a
hint: with locale en-US, 03/04/2024 gives 2024-03-04 and $1,234.56
gives USD (see the next sections).
Input
| Field | Type | Required | What it does |
|---|---|---|---|
items | array of strings | yes | 1 to 100,000 strings, one number, amount or date per string, each up to 200 characters. |
type | auto, number, currency or date | no (default auto) | auto detects the type of each string. The other values force one reading for every string. |
locale | string | no | A tag such as de, fr, en-GB, en-US, de-CH or sv. Settles the decimal separator, the day and month order of all-numeric dates, and shared currency symbols. |
dateOrder | auto, DMY, MDY or YMD | no (default auto) | Order of the parts in all-numeric dates. Overrides the order implied by locale. YMD applies only to dates with a two-digit year. |
The options apply to every string of the run. For lists in mixed conventions, group the strings by convention and start one run per group.
An empty or missing items list, more than 100,000 strings or an unknown
option value ends the run with a failure message; nothing is normalized and
nothing is charged.
Output
One dataset item per input string, in the same order. Every item has exactly these ten fields:
| Field | Type | Meaning |
|---|---|---|
input | string | The input string, unchanged. |
type | string | number, currency, date or unknown. |
value | number or null | The numeric value for number and currency, otherwise null. |
currency | string or null | ISO 4217 code when one reading is certain, otherwise null. |
iso | string or null | The date as YYYY-MM-DD for date, otherwise null. |
ambiguous | boolean | true when the string has more than one plausible reading. |
alternatives | array | The other readings. Each has a reason and a value, an iso date or a currency. |
confidence | string | high, medium or low. It is the outcome of the rules, not a measured probability. |
notes | string | Semicolon-separated codes: the rule applied and any flags. |
error | string or null | Error code when type is unknown, otherwise null. |
One example per type
Number, input 1 234,56:
{"input": "1 234,56","type": "number","value": 1234.56,"currency": null,"iso": null,"ambiguous": false,"alternatives": [],"confidence": "high","notes": "space_thousands_comma_decimal","error": null}
Currency, input 1.234,56 €:
{"input": "1.234,56 €","type": "currency","value": 1234.56,"currency": "EUR","iso": null,"ambiguous": false,"alternatives": [],"confidence": "high","notes": "dot_thousands_comma_decimal","error": null}
Date, input 3. März 2024:
{"input": "3. März 2024","type": "date","value": null,"currency": null,"iso": "2024-03-03","ambiguous": false,"alternatives": [],"confidence": "high","notes": "month_name","error": null}
Unknown, input 31.02.2024 (there is no 31 February):
{"input": "31.02.2024","type": "unknown","value": null,"currency": null,"iso": null,"ambiguous": false,"alternatives": [],"confidence": "low","notes": "invalid_date","error": "invalid_date"}
An ambiguous item, input 03/04/2024 with no hint:
{"input": "03/04/2024","type": "date","value": null,"currency": null,"iso": "2024-04-03","ambiguous": true,"alternatives": [{ "iso": "2024-03-04", "reason": "mdy_order" }],"confidence": "low","notes": "day_month_order_ambiguous","error": null}
Error codes
empty_input, not_a_string, input_too_long (over 200 characters),
unrecognized_input, unrecognized_number, unrecognized_date,
invalid_grouping, invalid_date, date_invalid_for_hint,
date_missing_year, date_missing_day, multiple_currencies,
number_out_of_range, internal_error.
Ambiguity rules
| Case | Example | Reading chosen | Alternatives | Flagged | Confidence |
|---|---|---|---|---|---|
| One separator followed by exactly three digits, no locale | 1.234, 1,234 | Thousands: 1234 | Decimal: 1.234 | yes | low |
The same, with a known locale | 1.234 with de gives 1234; with en-GB gives 1.234 | The locale's decimal separator decides | none | no | high |
| Both separators, or a space or apostrophe as thousands separator | 1.234,56, 1,234.56, 1 234,56, 1'234.50 | The last of the two separators is the decimal mark | none | no | high |
| All-numeric date where both orders are valid, no hint | 03/04/2024 | Day first: 2024-04-03 | Month first: 2024-03-04 | yes | low |
| All-numeric date where only one order is valid | 31/12/2024, 12/31/2024 | The valid order | none | no | high |
All-numeric date with a dateOrder or locale hint | 03/04/2024 with en-US gives 2024-03-04 | The hint; dateOrder wins over locale | none | no | high |
| Two-digit year | 31/12/24 | 00 to 68 read as 2000 to 2068, 69 to 99 as 1969 to 1999 | The same day in the other century | yes | medium at most |
| Two-digit year with dashes | 24-12-31 | Day first if valid; year first is also considered, and is chosen with locale sv | The other valid orders and the other century | yes | low or medium |
| Currency symbol shared by several currencies, no settling locale | 1 234,50 kr, $1,234.56, 12 lei, ¥500, Fr. 12.50 | currency is null; the value is still read | One per candidate currency | yes | medium at most |
| The same, with a settling locale | 1 234,50 kr with sv gives SEK | The locale's currency; note currency_from_locale | none | no | high |
Eight digits that also form a date, type auto | 20241231 | Number: 20241231 | The date 2024-12-31 | yes | medium |
Bare en, en-CA or fr-CA as locale | 03/04/2024 | No date order is implied; treated as no hint | Month first | yes | low |
Other rules that are choices of this Actor, not facts:
- A percent sign is noted (
percent) and the value is left as written:12,5 %gives 12.5, not 0.125. - A time after a date is dropped and noted (
time_ignored). £is read as GBP, although other pound currencies use the same sign.- Negative amounts are read from a leading or trailing minus and from
parentheses:
(1.234,56)gives -1234.56. 1.234,-andCHF 12.-are read as whole amounts.- Values are JSON numbers (double precision). Numbers with more than 15
significant digits are flagged
precision_loss. - An unknown
localeis ignored and noted (unknown_locale_ignored). - Indian digit grouping (
1,23,456) is not supported and returnsinvalid_grouping. - Month names are read in English, German, French, Spanish, Italian, Dutch, Portuguese, Polish and Swedish. Dates in other languages, relative dates ("yesterday") and dates with no year or no day return an error.
Use from an AI agent or MCP
The Actor takes one small JSON input and returns flat JSON items, so an
agent can call it as a tool through Apify's MCP server or the Apify API.
The tool arguments are the four input fields above; only items is
required. The result is the run's default dataset: one item per string, in
the input order, always with the same ten fields. The output below is what
the Actor's code returns for this input; tests/check_store_assets.js
compares the two JSON blocks against the code on every run. Pass a hint whenever the source of the strings is known: it settles the
separator, date order and shared-symbol cases listed in the table above.
Input:
{"items": ["1.234", "$1,234.56", "03/04/2024"],"locale": "en-US"}
Output (three dataset items):
[{"input": "1.234","type": "number","value": 1.234,"currency": null,"iso": null,"ambiguous": false,"alternatives": [],"confidence": "high","notes": "single_separator_three_digits_locale","error": null},{"input": "$1,234.56","type": "currency","value": 1234.56,"currency": "USD","iso": null,"ambiguous": false,"alternatives": [],"confidence": "high","notes": "comma_thousands_dot_decimal;currency_from_locale","error": null},{"input": "03/04/2024","type": "date","value": null,"currency": null,"iso": "2024-03-04","ambiguous": false,"alternatives": [],"confidence": "high","notes": "mdy_from_hint","error": null}]
A simple rule for an agent: use an item as it is when ambiguous is
false and error is null; otherwise look at alternatives, or call again
with a locale or dateOrder hint.
Price
Pay per event: USD 0.001 per result, which is USD 1.00 per 1,000 strings.
- One
resultevent is charged per dataset item, and one dataset item is written per input string.resultis the only event this Actor's code charges. - Items of type
unknown(strings that could not be read) are dataset items too and are charged like the others. - If you set a maximum charge for the run, the Actor stops when it is reached: the remaining strings are not processed and not charged, and the status message says how many were left.
- A run that fails input validation charges nothing.
Where the rule tables come from
The full statement is in src/DATA_SOURCES.md, shipped with the code. In
short:
- No file from Unicode CLDR, ICU or any other locale data project was copied, downloaded or transformed, so no third-party data licence applies to this Actor.
- The month names, currency symbols, decimal separator conventions and date order conventions were generated entry by entry by the AI model that built the Actor, from its general knowledge. They were not compared against an external reference dataset, so an entry can be missing or wrong.
- The currency codes are a subset of the ISO 4217 alphabetic codes.
- The two-digit year pivot is the rule of the POSIX
%yconversion. - The only runtime dependency is the Apify SDK (the
apifypackage). The normalizer itself uses Node core only.
How it was checked
A fixture script asserts the core module against expected values with
node:assert, including 20,000 fixed-seed garbage strings that must never
throw and must always return all ten fields. A second fixture script runs
the Actor's input validation and batch loop against the examples on this
page. Both were written by the same automated system that wrote the code:
they are consistency checks, not an independent verification.
Limits
- Deterministic, no LLM: fixed rules, so the same input and options always give the same output. It cannot read a string its rules do not cover.
- Ambiguous inputs are flagged and may be wrong: the Actor picks one
reading, sets
ambiguoustotrueand lists the others. - No accuracy guarantee. Unflagged items can be wrong too.
- Your input is not retained by the author beyond Apify's platform storage: it stays in your run's storage on Apify and the code sends it nowhere else.
- Built by an automated system of AI agents (Augeo), not written by a person; the checks above were written by the same system.
- 100,000 strings per run, 200 characters per string.
- One number, amount or date per string. It does not extract values from sentences or find several values in one string.
- No currency conversion and no exchange rates.
- No time zones: the time part of a timestamp is dropped.