Classify every column against a decider rather than a regex: calendar-checked dates, RFC 4291 addresses, and leading zeros kept out of integer columns
Initializing in your browser…
Count what is missing in five categories that add up to the grid, with the tokens that mean missing your choice
Sort by any number of columns, with the comparison stated: numbers by value, dates by day, text by a collation you choose
Generate realistic fake data for testing and development. Create names, usernames, emails, addresses, phone numbers, and more. Export to JSON or CSV format
Before importing into a typed database you need to know which columns are what, and which values will be rejected.
Input
zip: 01234, 02138, 10001, 90210 joined: 03/04/2025, 31/12/2025, 01/02/2025 active: 0, 1, 1, 0 score: 95.5, 88, 92.3, "not scored"
Inferred types
zip identifier VARCHAR(8) 2 of 4 carry a leading zero joined date DATE day first, proved by 31/12/2025 active boolean BOOLEAN every value is 0 or 1 score float NUMERIC 1 of 4 does not fit: "not scored"
Each answer comes with its reason. `zip` is text because two of its four values carry a leading zero and an integer column would destroy them. `joined` is day first because 31/12/2025 has no other reading, and the tool names that row. `active` is a boolean, which no single cell of it could have told you. `score` warns that one row will be rejected at import, not here.
What is actually in each column? This tool classifies every value into one of 18 types and then decides the column from all of them, reporting how it decided and what did not fit. Dates go through the calendar, addresses through an RFC 4291 parser, URLs through the browser's own URL parser, and digits with a leading zero are kept out of integer columns where they would be destroyed.
A CSV has no types: every value is a string, and something downstream has to guess. Most detectors guess with a chain of loose regular expressions tried in a fixed order, which means the ORDER decides the answer rather than the data. That failure mode is not theoretical. Measured against a 122-value corpus on 2026-09-01, the previous version of this tool classified every date in the corpus as a telephone number, because its phone pattern sat above its date pattern and happened to match 2025-03-04. It also read 14:30:00 as an IP address, accepted 999.1.1.1 and 2025-02-29, and refused http://example.com/path?q=1#frag as a URL. It scored 80 of 122.
This version asks something that can actually decide. A date is checked against the calendar, so 2025-02-29 is not a date (2025 is not a leap year) while 2024-02-29 is, and month 0 and month 13 are refused. A time is checked against the clock, so 25:00 and 14:60 are not times, while 24:00 and a 23:59:60 leap second are. An address goes through the same RFC 4291 parser the subnet calculator uses. A URL goes through the WHATWG URL parser that the browser itself uses, so any scheme counts and a file name does not. An email is checked against the WHATWG HTML valid e-mail address production, the one every HTML5 form enforces, which is worth knowing about because it deliberately accepts someone@localhost. A number goes through a stated decimal grammar, so +8 and .5 are numbers and 0x1F, 1_000 and Infinity are not. The corpus score is now 122 of 122.
Two types were missing from the vocabulary and both cost real data. An identifier is digits that are not a quantity: 01234 is a postcode and 007 is a padded code, and storing either as an integer loses the zero permanently. If ANY value in a column carries a leading zero the whole column is typed as text, because the damage is one-directional. And an explicit NULL, N/A or NaN is not an empty cell; the two are counted separately on every column, and a column that is entirely null is reported as such rather than falling through to text.
Some questions a single cell cannot answer and a column can, so the two are asked separately. A column whose values are all 0 and 1 is a boolean, which no cell of it could tell you. A column of dd/mm against mm/dd dates is settled by any cell whose first field is above 12: given 03/04/2025 and 31/12/2025 together, the tool reports day first and names 31/12/2025 as the proof. When nothing in the column settles it, it says so and offers the choice rather than picking in silence.
Every column also reports how many of its values do NOT fit the chosen type, with examples, and says plainly that a column declared integer with one text row fails at import rather than here. That is the number that decides whether a load will succeed.
Get a CREATE TABLE whose types the data will actually satisfy, with an explicit count of the rows that would be rejected if you used the majority type anyway.
Find the columns of postcodes, account numbers and padded codes that a naive import would turn into integers, losing the leading zeros for good.
Work out whether a dd/mm/yyyy column is day first or month first from the data itself, and see which row proves it.
See how many cells in each column are the odd ones out, what they are, and whether the nulls in the file are empty cells or literal NULL text.
Because storing 01234 as an integer makes it 1234 and the leading zero cannot be recovered. If any value in the column carries a leading zero the whole column is typed as text, and the card says so. The damage only runs one way, so the rule does too.
One cell cannot say. The column often can: if any other cell has a first field above 12, such as 31/12/2025, the column is day first and the tool names that cell as the proof. If nothing settles it, the column is reported as unresolved with a warning, and you can set the date order by hand.
Because it is one, by the definition browsers enforce. The WHATWG HTML valid e-mail address production allows a domain with no dot so that intranet hosts work, and a real <input type="email"> accepts it. The tool notes that such an address will not deliver publicly.
An empty cell holds nothing. A null marker is a cell holding the text NULL, N/A, NA, NaN, None or a bare dash. They are counted separately on every column because they mean different things: one is a missing field, the other is a value your source system chose to write.
The share of non-empty, non-null cells that match the chosen type. Alongside it the card gives the raw count of values that do not fit, with examples, because that count is what decides whether an import succeeds.
It updates immediately without re-reading the file. The analysis is a pure function of the data and the settings, so switching dialect or date order is instant.
Rows and columns are parsed and transformed in memory in your browser. No record ever reaches a server.