Mixed date formats sort wrong, break joins, and quietly destroy month-over-month charts. How to detect the mess in one pass, then parse each format explicitly.
Here is a bug that produces no error message: a date column containing
2026-01-05, 2026/02/11, 03/12/2026 and 2026年4月8日
in the same column. pandas will happily coerce most of it, sort it wrong, and hand you a
month-over-month chart that lies.
03/12/2026 parses as 3 December under %d/%m/%Y and as
12 March under %m/%d/%Y. Both "work". If your month grouping silently switches
convention halfway down the column, two months of revenue land in the wrong bucket and the trend line
inverts. Nobody catches it because nothing throws.
import re
from collections import Counter
PATS = [
(r"^\d{4}-\d{2}-\d{2}$", "YYYY-MM-DD"),
(r"^\d{4}/\d{2}/\d{2}$", "YYYY/MM/DD"),
(r"^\d{2}/\d{2}/\d{4}$", "DD/MM or MM/DD"), # ambiguous on purpose
(r"^\d{4}年\d{1,2}月\d{1,2}日$", "CN"),
]
hits = Counter()
for v in df["order_date"].dropna().astype(str).head(5000):
for pat, name in PATS:
if re.match(pat, v.strip()):
hits[name] += 1; break
else:
hits["unrecognized"] += 1
print(hits) # the diagnosis, before any parsing
If more than one bucket has counts, the column is mixed. That single print saves an afternoon.
Never rely on the inferencer. Map format to parser:
def parse_one(v):
s = str(v).strip()
m = re.match(r"^(\d{4})年(\d{1,2})月(\d{1,2})日$", s)
if m: return datetime(*map(int, m.groups()))
for f in ("%Y-%m-%d", "%Y/%m/%d", "%d/%m/%Y", "%Y-%m-%d %H:%M"):
try: return datetime.strptime(s, f)
except ValueError: pass
return None
df["date"] = df["order_date"].map(parse_one)
print(df["date"].isna().sum()) # must be 0, or you know exactly what is left
Then check the failures, not the successes. A nonzero NaN count is the honest signal.
When every value has a day ≤ 12, the data cannot tell you which convention it is. Do not guess — check another column (a timezone, a fiscal period, an export locale), or ask. Guessing wrong shifts a third of your rows by up to eleven months.
CSV Doctor counts each format in every date column and prints the
breakdown, along with junk-in-numeric-columns, encoding and duplicate checks. It is free —
download it here and run
python csv_doctor.py --in yourfile.xlsx. If it reports HIGH, fix that before you build
anything on top of the data.
30-second health check for any spreadsheet: encoding, mixed date formats, junk in numeric columns.
Download free