Unexpected behavior of %+02d in Sprintf() and friends

210 views
Skip to first unread message

Eric Raymond

unread,
Aug 28, 2018, 12:09:26 PM8/28/18
to golang-nuts
Under Go 1.10.1, feeding an 0 value to a %+02d specifier sometimes yields  "+0", not "+00". The attached tiny Go program may reproduce this behavior.  I say "may" because I first observed it in a series of unit tests of date format conversions - in different format strings %+02d expanded differently.  I haven't found a pattern to this, or I'd report it. On my system this program, at least, has repeatable behavior.

If this behavior were consistent, I'm not sure it would be a bug. It's possible that the sign is supposed to be counted as part of the number width; if so, it's an interesting question whether this is the right thing when explicit sign is forced by +.  The documentation is unclear.

The apparent inconsistency worries me.  There may be some state in the form,at-interpretation code that is not always tracked correctly.

In accordance with the Contribution Guidelines, I'm tossing  the question out here for a sanity check before throwing it on the bugtracker.  Have there been any similar reports?
gobug1.go

peterGo

unread,
Aug 28, 2018, 4:49:02 PM8/28/18
to golang-nuts
Eric,

"Width is specified by an optional decimal number immediately preceding the verb. If absent, the width is whatever is necessary to represent the value. "


Width is two.

Peter

peterGo

unread,
Aug 28, 2018, 4:57:18 PM8/28/18
to golang-nuts
Eric,

For example,

package main

import (
    "fmt"
    "runtime"
)

func main() {
    // Correctly prints "+0 00\n" as +00 00
    fmt.Printf("%s: %+03d %02d\n", runtime.Version(), 0, 0)
}

Output:

go1.10.3: +00 00


Widths three and two.

Peter

Borman, Paul

unread,
Aug 28, 2018, 7:35:26 PM8/28/18
to Eric Raymond, golang-nuts
I believe +0 is correct.  That is 2 bytes which is what you requested with %+02d and the + takes up the first byte and 0 fits in the second byte.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
<gobug1.go>

Eric Raymond

unread,
Aug 29, 2018, 7:53:35 AM8/29/18
to golang-nuts
On Tuesday, August 28, 2018 at 4:49:02 PM UTC-4, peterGo wrote:
"Width is specified by an optional decimal number immediately preceding the verb. If absent, the width is whatever is necessary to represent the value. "


Width is two.

Thanks for the clarification.  May I recommend appending to that sentence "(including the leading sign, if any, even if the sign is forced by a + modifier)"?

I still think i saw apparently inconsistent behavior.  I'm still writing unit tests involving date conversions, so I'm going to try to reproduce this and turn in an actionable report.

Borman, Paul

unread,
Aug 29, 2018, 7:57:23 AM8/29/18
to Eric Raymond, golang-nuts
Is it possible you used the format string “+%02d” vs “%+02d”?  The first will give you the +00 you expected while the second is +0, as discussed.

Eric Raymond

unread,
Aug 29, 2018, 8:12:41 AM8/29/18
to golang-nuts
On Wednesday, August 29, 2018 at 7:57:23 AM UTC-4, Borman, Paul wrote:
Is it possible you used the format string “+%02d” vs “%+02d”?  The first will give you the +00 you expected while the second is +0, as discussed.

Alas, no.  Here's the line from my test program:

fmt.Printf("%s: %+02d %02d\n", runtime.Version(), 0, 0)

In the original context where I saw the behavior, I was generating [+-]hhmm strings corresponding to timezone offsets. The sign in the output could not be fixed in the format; it had to be derived from the offset.




Reply all
Reply to author
Forward
0 new messages