-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
proposal: time: allow scientific notation in ParseDuration #67076
Comments
What sort of application represents time duration like this? |
In this case, it was MiniSat, an old but still often used C++ code. MiniSat normally doesn't output times in scientific notation, but I suspect that it uses |
I would be opposed to adding this complexity to |
Conceptually, time.Duration is fixed-point. Allowing scientific notation may lure one into the false believe that e. g. "1e-10s" is a representable duration. |
But how is that different from "0.0000000001s", which is equally non-representable? |
"0.0000000001s" looks funky. "100ps" and "1e-10s" don't. The former doesn't parse. |
I don't follow. We're talking about parsing input, not producing output. Who cares what inputs look funky? They'll be normalized on output.
"0.0000000001s" parses as 0ns, as expected for an integer type with nanosecond resolution. "100ps" doesn't parse because units smaller than nanoseconds aren't recognized. This is already documented:
Despite My proposal is simply that
|
I guess my interpretation of Principle of Least Surprise differs from yours, but would you also want time.ParseDuration to accept any of "0xap1us", "0x.dp+0h" or "+InfhNANns"? |
I wouldn't expect it to accept "+InfhNANns" because that can't be represented by a That said, my main concern is scientific notation because programs in many languages, including Go, have an equivalent of C's |
This feels like asking to hiding alot of magic and rounding heuristics inside time.ParseDuration(), since there are alot of floating point numbers that will not have an exact int64 nanosecondsrepresentation. What should ParseDuration() do then? It could hide the sloppy inexact conversion, returning an approximation. Or it could return an error. What are you going to do with the error? Probably fall back on the following preferred approach (below) anyway. What are you going to do with a sloppy inexact conversion? Will you even notice it? Will not noticing it lead to bugs? Some, almost surely. Will the new heuristic be acceptable for all current users of time.ParseDuration()? Unlikely, if they are depending on the current set error producing inputs. I would much rather read Go application code that makes explicit what is going on, like first using f := strconv.ParseFloat(s, 64) on a string s that has the 's' (for seconds duration) suffix verified and removed, and then deliberately displaying the rounding/conversion to the int64 domain. Then I can readily write tests for the cases that matter to my application, and easily tweak the behaivor to what the application at hand requires. In other words, it is pretty easy to write in user/application code already, using strconv.ParseFloat() itself, and it would be better practice to do that. |
Once again, the core of my proposal is for |
@spakin: An addendum to your proposal. The "A [Go] decimal floating-point literal consists of an integer part (decimal digits), a decimal point, a fractional part (decimal digits), and an exponent part (e or E followed by an optional sign and decimal digits). One of the integer part or the fractional part may be elided; one of the decimal point or the exponent part may be elided. An exponent value exp scales the mantissa (integer and fractional part) by 10ᵉˣᵖ." "A [JSON] number is a sequence of decimal digits with no superfluous leading zero. It may have a preceding minus sign (U+002D). It may have a fractional part prefixed by a decimal point (U+002E). It may have an exponent, prefixed by e (U+0065) or E (U+0045) and optionally + (U+002B) or – (U+002D). The digits are the code points U+0030 through U+0039." For example:
The Adapting the current All current Test results for decimal floating-point numbers are shown in the C library floating-point examples. Test results for @spakin's Go Playground
and
|
Sounds good to me, @peterGo. Thanks for the work you put into testing |
I don't buy the JSON argument: if you append a unit, what you have is no longer a JSON number, but a string with semantics not covered by JSON. E. g. This isn't about implementability. If I'm allowed a historical example, to this day people moan about "0"-prefixed octal integer literals. Standardizing parsers with obtuse behaviours, if at the time of implementing auspicious, increase complexity forever with ever diminishing value. I cannot read e. g. |
Proposal Details
Issue
I encountered this issue while parsing the output of an application I was working with:
strconv.ParseFloat
accepts numbers expressed in scientific notation.strconv.ParseFloat("3.336e-6", 64)
, for example, works as expected.time.ParseDuration
does not accept numbers expressed in scientific notation.time.ParseDuration("3.336e-6s")
, for example, fails withunknown unit "e-" in duration "3.336e-6s"
.A Go Playground demonstration of this limitation in
time.ParseDuration
can be found here: https://go.dev/play/p/G-1FveHxpZ3Proposal
I propose that
time.ParseDuration
be enhanced to allow durations expressed using scientific notation.The text was updated successfully, but these errors were encountered: