-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow less than expected digits when parsing time with decimals #5317
Allow less than expected digits when parsing time with decimals #5317
Conversation
I'm not sure that everyone will expect Our time format is similar to standard unix time format, what do they do? |
Currently, If the length is fixed to maximum precision, both can be used with the same format. If reduced precision should also be supported, we'll probably need two different formats. For the fraction variant it should also be possible to define the number of digits (i.e. precision). My suggestion is to have (A) This PR would implement (A). (B) and (C) should follow, but are probably not too important. |
Python uses Ruby uses I suggest: |
I don't find a use case for parsing %N or %L as integer entities inside a time/date time string. Implementing I could take care of adding |
It is not very common to use nanoseconds as integer. I've just seen an example of dates being formatted as With all these formats with different precision, it is clear how the formatter should behave. But what about the parser? Should it complain if it gets more or less than 3, 6, or 9 digits? I don't know if there are date formats that demand for a specific number of digits. |
I've just pushed the handling of 3N, 6N, 9N with some refactors mainly in the parser. All the options allow less digits when parsing and pad when formatting. |
I'm not sure if the formats with reduced precision should just truncate additional digits. Parsing If the number of digits does not match, it should either be stric and fail or allow more digits than expected but recognize their value. I think it would be safe to let all of them consume as much digits as there are available. The only significance should be in the formatter. |
1d4b5a8
to
a41c32c
Compare
@straight-shoota you are right, it looks weird. And ruby does the same, all the digits are preserved. |
src/time/format/parser.cr
Outdated
second_decimals 9 | ||
end | ||
|
||
private def second_decimals(precision) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is unnecessary when all behave the same.
a41c32c
to
7f164fe
Compare
I think this is bad: in formats such as |
@RX14 I think that won't happen in a real use case. Also, nano and microsecond parsing was already consuming 12 consecutive digits. Maybe we could detect at runtime some invalid patterns: Some delimiter char or non digit pattern should follow a |
@bcardiff it might be rare but I don't see why we shouldn't support it. We should support parsing |
ruby did it again 🎩 . It parses
I would defer the border case for other PR. I think that improving the parsing with this PR is valuable as is given the precision of nanoseconds is not always present in string representation of times. |
There shouldn't be a border case: we should always be strict. I don't see why merging something which could so easilly be improved is a good idea? |
@RX14 With be strict do you mean to read only as many digits as the format describes and fail if there are more (and can't be consumed by the next pattern)? |
@straight-shoota basically. Although, if we don't currently fail if there's left-over pattern, we shouldn't change that in this PR. |
7f164fe
to
f7c9287
Compare
Now Rebased on master. I would merge it without squashing if approved. |
I think it's better off being squashed though: it's one logical change. |
It seems like |
Ah no, I see it was merged in the same entry with Also, I'm think Additionally, the N-formats are not in correct alphabetical order (though that has been the case for |
This PR allows
Time.parse
to use less digits in the fraction part than the specified with the%N
or%L
optionsSo
Time.parse("2016-09-09 17:03:28.456789", "%F %T.%N")
will mean456789000
nanoseconds. Before this PR the meaning was456789
which does not correspond with the decimals semantic.Without this PR parsing dates with 1, 2, 6 digits (or other than 3 or 9) was not straight. The user would need to pad 0 before parsing. I came through this while parsing datetime from mysql which have at most 6 digits.
I don't think that making
%N
or%L
options relaxed in the amount of digits to parse is problematic. The other path would be to have modifiers with strict / flexible decimals for parsing, yet always strict for printing.The first specs might look a bit weird since parsing
1
as microseconds should be treated as 100 microseconds since the%L
modifier should be used after a decimal separator. Similar1
as nanoseconds should be treated as 100000000 nanoseconds.