feat: improve date parsing - #245
Conversation
0f8d074 to
ab90678
Compare
# Conflicts: # csv_detective/detection/formats.py # csv_detective/parsing/columns.py # csv_detective/validate.py # tests/test_fields.py
…ns, optional format parts
|
A necessary change! The logic looks good, but I need to take more time to review all changes more carefully :) |
bolinocroustibat
left a comment
There was a problem hiding this comment.
LGTM, with two remarks
There was a problem hiding this comment.
Here, unsure why do we drop this format ? Because not an known separate format and this can be included in date.py just as a type of date format like any other ?
[the comment was for the deleted date_fr file, not appearing on the right one here + this has been managed since by commit 48219e8]
|
@ThibaudDauce maybe to add to your PR description : I found the answer to my question about how strict we want to be with mixed separators in a date format : your new function def separator_of(val: str) -> str | None:
"""The single separator the value uses, "" if it uses none, None if it mixes several."""
found = {
char
for index, char in enumerate(val)
if char in SEPARATORS
# the full stop of an abbreviated month is not a separator ("15 janv. 1985")
and not (char == "." and index and val[index - 1].isalpha())
}
if len(found) > 1:
return None
return found.pop() if found else ""is a breaking change if I understand well : before, if we consider only The thing is, I don't know why it was accepted before and that might be because some datasets were using this shape. I believe this is a bad practice and we don't want to encourage this kind of format, but we need to keep in mind some datasets could loose their date columns and associated metadata to string only. |
|
Also, one thing, not introduced here but we might want to include it (or in a second PR) : in remaining_tests_per_col = {
col: {
fmt_label
for fmt_label, fmt in formats.items()
# keeping formats that have the valid python type
if fmt.python_type == pytype
# except if the column label doesn't fit
and fmt_label not in mandatory_label_skip.get(col, set())
# we already know pure types are valid, only formats remain
and fmt_label != pytype
}
for col, pytype in columns.items()
}We might want to add this exception so it performs as well on parquet and csv ? On another hand, we could say that parquet files are supposed to be typed and if the user didn't declare cleanly a type that was available amongst parquet ones (like a |
This one is not new: And it's not only about dates, the So I'm more with your second option: parquet is typed, if the user declared a string we |
Yes I think it's more a bug fix, I'm not sure we wanted to have mixed separators in dates, but the previous code allowed this… But it seems really weird to accept that… |
|
Ok so recap : Parquet string cols not being tested for date format Mixed separators not allowed anymore in date columns |
|
@ThibaudDauce @estellebertrand I'm getting a bit lost with this PR to review. Would that make sense to break it into smaller, more readable PRs, or would that be overcomplicated? |
Replace fix: cast dd/mm/yyyy dates day-first (was silently swapping day and month) #268
add
date_formatto profile to have a faster cast in hydraby finding a unique date format for the column it prevent having US dates (month first) vs FR dates (day first) mixed
date_fris removed,datereads the same values and gives them a realdatepython_type. Stored analyses naming it still validate, nothing to regenerate.we do not accept mixed separators from now on
2026/04-14for example is no longer a datehydra stats (require perf: cast dates with the format inferred by csv-detective hydra#470):
Some analyses will be invalidated and replayed after the merge. Values
dateutilused to read as dates and that we don't detect anymore, on the files I have locally:D. 2.9 ; E. 0.6M 1089134,13848.8256130680428426202501010000Everything but the last one is noise
dateutilwas finding in phone numbers, latitudes and museum inventory numbers.AAAAMMJJHHMNis a real one: it's nowdatetime_naivewhere it wasdate, so the column type changes in the db (it holds hours and minutes that thedatetype was dropping).