Re: Are there a way to custom format a number in Golang?

2930 views
Skip to first unread message

Volker Dobler

unread,
Jun 4, 2013, 5:44:33 PM6/4/13
to golan...@googlegroups.com, mobiled...@gmail.com
Am Dienstag, 4. Juni 2013 22:55:40 UTC+2 schrieb mobiled...@gmail.com:
Are there a way to custom format a number in Golang?  
 Like this in C#:
value = 1234567890;
 Console.WriteLine(value.ToString("(###) ###-####"));
 // Displays (123) 456-7890


value := 1234567890
str := strconv.Itoa(value)
fmt.Printf("(%s) %s-%s", str[0:3], str[3:6], str[6:])

 V.

Rob Pike

unread,
Jun 4, 2013, 11:41:32 PM6/4/13
to mobiled...@gmail.com, golan...@googlegroups.com
Go is a programming language.

-rob

peterGo

unread,
Jun 5, 2013, 1:04:22 PM6/5/13
to golan...@googlegroups.com, mobiled...@gmail.com
Yes, write a String function for the type. For example,

package main

import (
    "fmt"
)

type PhoneNo struct {
    phoneNo uint64
}

func NewPhoneNo(phoneNo uint64) *PhoneNo {
    return &PhoneNo{phoneNo: phoneNo}
}

func (p PhoneNo) String() string {
    // TODO(anyone) E.123 : Notation for national and international telephone numbers
    // http://www.itu.int/rec/T-REC-E.123/en
    // TODO(anyone) National conventions for writing telephone numbers
    // http://en.wikipedia.org/wiki/National_conventions_for_writing_telephone_numbers
    no := p.phoneNo % 1e4
    xc := p.phoneNo / 1e4 % 1e3
    phoneNo := fmt.Sprintf("%03d-%04d", xc, no)
    ac := p.phoneNo / 1e7 % 1e3
    if ac != 0 {
        phoneNo = fmt.Sprintf("(%03d) %s", ac, phoneNo)
    }
    pfx := p.phoneNo / 1e10
    if pfx != 0 {
        phoneNo = fmt.Sprintf("%d %s", pfx, phoneNo)
    }
    return phoneNo
}

func main() {
    fmt.Println(NewPhoneNo(1234567))
    fmt.Println(NewPhoneNo(1234567890))
    fmt.Println(NewPhoneNo(18004567890))
}

Output:

123-4567
(123) 456-7890
1 (800) 456-7890

http://play.golang.org/p/CngOSrSrqS

Peter

peterGo

unread,
Jun 5, 2013, 1:06:37 PM6/5/13
to golan...@googlegroups.com, mobiled...@gmail.com
s/String function/String method/

Michael Jones

unread,
Jun 5, 2013, 1:41:54 PM6/5/13
to mobiled...@gmail.com, golang-nuts
It seems more complicated than that...


...which leads to...


Is that what you really want? If so, as Rob said, you can program that. COBOL has something like this in its PICTURE clause.


On Tue, Jun 4, 2013 at 1:55 PM, <mobiled...@gmail.com> wrote:
Are there a way to custom format a number in Golang?  
 Like this in C#:

value = 1234567890;
 Console.WriteLine(value.ToString("(###) ###-####"));
 // Displays (123) 456-7890

--
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/groups/opt_out.
 
 



--
Michael T. Jones | Chief Technology Advocate  | m...@google.com |  +1 650-335-5765
Message has been deleted

Volker Dobler

unread,
Jun 5, 2013, 3:29:54 PM6/5/13
to golan...@googlegroups.com, mobiled...@gmail.com
Am Mittwoch, 5. Juni 2013 20:06:51 UTC+2 schrieb mobiled...@gmail.com:
I can program that of course. Probably can save time if 
there is a library. This is commonly used.

First: Each country has its own phone number formatting style.

Second: This is not an instance of the "2 weeks in the lab will
save you 4 hours in the library." Searching a package which does
such a trivial task is time wasted.

V.

Michael Jones

unread,
Jun 5, 2013, 4:14:18 PM6/5/13
to Volker Dobler, golang-nuts, mobiled...@gmail.com
The full description at the Microsoft website is interesting. It has a mechanism for formatting positive, zero, and negative numbers. You could imagine a scheme for formatting based on the number of digits (or maybe it's already possible and I overlooked it.)

Michael


--
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/groups/opt_out.
 
 

Michael Jones

unread,
Jun 5, 2013, 7:32:39 PM6/5/13
to so.pe...@gmail.com, golang-nuts, Constantine Vassil
I'm curious what should happen in that format with short (7-digit) numbers.

I think 123-4567 makes sense, but "() 123-4567" or "(   ) 123-4567" do not. Does the C# formatting library drop the parentheses on the left when there are not enough digits?

The Go code somebody wrote for you does an explicit test, but I'm curious if the PICTURE-like specification has a rule like "fill in from right to left and when the digits run out, stop copying anything." I looked for this on the website but did not see it.


On Wed, Jun 5, 2013 at 11:55 AM, <so.pe...@gmail.com> wrote:
Michael,

NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area (NPA) code, commonly called an area code, followed by a seven-digit local number. The format is usually represented as

   NXX-NXX-XXXX

where N is any digit from 2 through 9 and X is any digit from 0 through 9.

http://www.nanpa.com/about_us/abt_nanp.html

It's a problem for even the simplest US numbers, for example, 299-299-0000.

Peter

peterGo

unread,
Jun 5, 2013, 10:24:58 PM6/5/13
to golan...@googlegroups.com, so.pe...@gmail.com, Constantine Vassil
Michael,

The C# format codes are derived from Microsoft Excel.

Number format codes
http://office.microsoft.com/en-us/excel-help/number-format-codes-HP005198679.aspx

Create a custom number format
http://office.microsoft.com/en-us/excel-help/create-a-custom-number-format-HP010342372.aspx

Excel has a special conditional format code for phone numbers.

Excel 2010
Format Cells
Locale: English (U.S.)
Category: Special
Type: Phone Number
Format Code: [<=9999999]###-####;(###) ###-####

As you can see, 1234567, which is <=9999999, is 123-4567 and 1234567890, which is not <=9999999, is (123) 456-7890, which follows the ITU-T standard.

ITU-T
TELECOMMUNICATION
STANDARDIZATION SECTOR
OF ITU

Notation for national and international
telephone numbers, e-mail addresses and
Web addresses

E.123 (02/2001)

7  Procedural symbols

A procedural symbol is a symbol which tells the subscriber how to dial. Such symbols should not appear in a finger hole or on a push button because they are not to be dialled.

7.2  Use of parentheses

The symbol ( ) (parentheses) should be used to indicate that the digits within the ( ) are not always dialled.

The ( ) should enclose:

• the trunk prefix and trunk code in a national number;
• the trunk code when the trunk prefix is not in universal use within a country.

This is done to remind the user not to dial the enclosed digits for calls within the same numbering area.

The ( ) should not be used in an international number.

T-REC-E.123-200102-I!!PDF-E.pdf
http://www.itu.int/rec/T-REC-E.123-200102-I/en

Peter


On Wednesday, June 5, 2013 7:32:39 PM UTC-4, Michael Jones wrote:
I'm curious what should happen in that format with short (7-digit) numbers.

I think 123-4567 makes sense, but "() 123-4567" or "(   ) 123-4567" do not. Does the C# formatting library drop the parentheses on the left when there are not enough digits?

The Go code somebody wrote for you does an explicit test, but I'm curious if the PICTURE-like specification has a rule like "fill in from right to left and when the digits run out, stop copying anything." I looked for this on the website but did not see it.

peterGo

unread,
Jun 5, 2013, 11:01:31 PM6/5/13
to golan...@googlegroups.com, so.pe...@gmail.com, Constantine Vassil
Michael,

Microsoft Excel has a bug in its Phone Number format code; 800 numbers display as (1800) 123-4567, instead of 1-800-123-4567. The Microsoft Excel format code should be:

[<=9999999]###-####;[<=9999999999](###) ###-####;#-###-###-####

Peter

peterGo

unread,
Jun 5, 2013, 11:08:47 PM6/5/13
to golan...@googlegroups.com, mobiled...@gmail.com
Here's a revised PhoneNo String method, which properly formats 800 numbers.


package main

import (
    "fmt"
)

type PhoneNo struct {
    phoneNo uint64
}

func NewPhoneNo(phoneNo uint64) *PhoneNo {
    return &PhoneNo{phoneNo: phoneNo}
}

func (p PhoneNo) String() string {
    // TODO(anyone) E.123 : Notation for national and international telephone numbers
    // http://www.itu.int/rec/T-REC-E.123/en
    // TODO(anyone) National conventions for writing telephone numbers
    // http://en.wikipedia.org/wiki/National_conventions_for_writing_telephone_numbers
    no := p.phoneNo % 1e4
    xc := p.phoneNo / 1e4 % 1e3
    phoneNo := fmt.Sprintf("%03d-%04d", xc, no)
    if p.phoneNo <= 9999999 {
        return phoneNo

    }
    ac := p.phoneNo / 1e7 % 1e3
    if p.phoneNo <= 9999999999 {

        phoneNo = fmt.Sprintf("(%03d) %s", ac, phoneNo)
        return phoneNo

    }
    pfx := p.phoneNo / 1e10
    if pfx != 0 {
        phoneNo = fmt.Sprintf("%d-%03d-%s", pfx, ac, phoneNo)

    }
    return phoneNo
}

func main() {
    fmt.Println(NewPhoneNo(1234567))
    fmt.Println(NewPhoneNo(1234567890))
    fmt.Println(NewPhoneNo(18004567890))
}

Output:

123-4567
(123) 456-7890
1-800-456-7890

http://play.golang.org/p/_gS0N2rMYc

Peter

Michael Jones

unread,
Jun 6, 2013, 11:53:27 AM6/6/13
to peterGo, golang-nuts, Constantine Vassil
Peter, thanks! I had no idea about this excel-C#-case/if-conditional-formatting until this email thread, so I've learned something. It is a good day when you learn something.

I wonder if such "implicit computation formatting" makes sense in a programming language. I see why it would be valuable in a spreadsheet cell, where the choice between the extremes of a fixed format or a call out to some script language to do the work might be met with a simpler, middle path of smart, data-driven format codes. But I'm thinking about a C# or Go developer in the same situation. When would I want to rephrase cases and conditions that I could put in clear programming langueg code into such an expression? My only answer so far is when the formatting changes by language or locale such that the format string could be part of localization. The currency symbol, the role of ',' and '.', the formatting of phone numbers and dates, things like this could be lifted from explicit compiled code to either a configured string set or a local-aware library. That's the good. The bad would be the awkwardness of learning (and having future maintainers understand) this sub-language.

if x <= 9999999 {
    format one way
} else {
    format the other way
}

vs

Magic("[<=9999999]one way;other way", ...)

Hmmm....


--
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/groups/opt_out.
 
 
Reply all
Reply to author
Forward
0 new messages