Git Product home page Git Product logo

go-humanize's Introduction

Humane Units Build Status GoDoc

Just a few functions for helping humanize times and sizes.

go get it as github.com/dustin/go-humanize, import it as "github.com/dustin/go-humanize", use it as humanize.

See godoc for complete documentation.

Sizes

This lets you take numbers like 82854982 and convert them to useful strings like, 83 MB or 79 MiB (whichever you prefer).

Example:

fmt.Printf("That file is %s.", humanize.Bytes(82854982)) // That file is 83 MB.

Times

This lets you take a time.Time and spit it out in relative terms. For example, 12 seconds ago or 3 days from now.

Example:

fmt.Printf("This was touched %s.", humanize.Time(someTimeInstance)) // This was touched 7 hours ago.

Thanks to Kyle Lemons for the time implementation from an IRC conversation one day. It's pretty neat.

Ordinals

From a mailing list discussion where a user wanted to be able to label ordinals.

0 -> 0th
1 -> 1st
2 -> 2nd
3 -> 3rd
4 -> 4th
[...]

Example:

fmt.Printf("You're my %s best friend.", humanize.Ordinal(193)) // You are my 193rd best friend.

Commas

Want to shove commas into numbers? Be my guest.

0 -> 0
100 -> 100
1000 -> 1,000
1000000000 -> 1,000,000,000
-100000 -> -100,000

Example:

fmt.Printf("You owe $%s.\n", humanize.Comma(6582491)) // You owe $6,582,491.

Ftoa

Nicer float64 formatter that removes trailing zeros.

fmt.Printf("%f", 2.24)                // 2.240000
fmt.Printf("%s", humanize.Ftoa(2.24)) // 2.24
fmt.Printf("%f", 2.0)                 // 2.000000
fmt.Printf("%s", humanize.Ftoa(2.0))  // 2

SI notation

Format numbers with SI notation.

Example:

humanize.SI(0.00000000223, "M") // 2.23 nM

English-specific functions

The following functions are in the humanize/english subpackage.

Plurals

Simple English pluralization

english.PluralWord(1, "object", "") // object
english.PluralWord(42, "object", "") // objects
english.PluralWord(2, "bus", "") // buses
english.PluralWord(99, "locus", "loci") // loci

english.Plural(1, "object", "") // 1 object
english.Plural(42, "object", "") // 42 objects
english.Plural(2, "bus", "") // 2 buses
english.Plural(99, "locus", "loci") // 99 loci

Word series

Format comma-separated words lists with conjuctions:

english.WordSeries([]string{"foo"}, "and") // foo
english.WordSeries([]string{"foo", "bar"}, "and") // foo and bar
english.WordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar and baz

english.OxfordWordSeries([]string{"foo", "bar", "baz"}, "and") // foo, bar, and baz

go-humanize's People

Contributors

aleksi avatar annismckenzie avatar bbigras avatar bramp avatar clconway avatar dmitshur avatar dustin avatar fkautz avatar flexd avatar hurf avatar jille avatar joycebrum avatar jsvisa avatar kebhr avatar maximal avatar mholt avatar sapk avatar setomits avatar stereosteve avatar tdewolff avatar tompreston avatar tucksaun avatar tv42 avatar yyoshiki41 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-humanize's Issues

PluralWord should return singular word with a 0 quantity

What:
When using the functions Plural/PluralWord with a quantity of 0, those functions return the plural word.

Why:
Plural function is based on PluralWord function. This last one is strictly checking that the quantity is equal to 1 in order to return the singular word.
However, it should also return the singular word in case the value is 0.

Ex: 2 pending requests, 1 pending request, 0 pending request

Add i18n to go-humanize

Here is a proposal to support i18n :

  • Add new types
type BaseHumanizer {}
type EnglishHumanizer {
    BaseHumanizer
}
var Default EnglishHumanizer
var English EnglishHumanizer
  • Move all funcs to StandardHumanizer or EnglishHumanizer
func (h *BaseHumanizer) Ftoa(num float64) string {
    [...]
}
func Ftoa(num float64) string {
    return Default.Ftoa(num)
}

func (h *EnglishHumanizer) Ordinal(x int) string {
    [...]
}

func Ordinal(x int) string {
    return DefaultHumanizer.Ordinal(x)
}
  • Add the definition for french :
type FrenchHumanizer {
    BaseHumanizer
}
var French FrenchHumanizer

func (h *FrenchHumanizer) Ordinal(x int) string {
    [...]
}

Usage :

fmt.Println(humanizer.Ordinal(1)) => "1st"
fmt.Println(humanizer.Default.Ordinal(1)) => "1st"
fmt.Println(humanizer.English.Ordinal(1)) => "1st"
fmt.Println(humanizer.French.Ordinal(1)) => "1er"

Rounding settings

This lets you take a time.Time and spit it out in relative terms. For example, 12 seconds ago or 3 days from now.
©

I have some issues with this format, in most cases difference between 1,5 days and 1 or 2 days is significant for me but there's no way to tune this format.

Duration way (timeA.Sub(timeB).Truncate(time.Second)) doesn't look good too: 2880h7m59s.

It would be awesome to be able to set minimal detailisation to print.

Commaf which rounds to X decimal places

humanize.Commaf(10772.08207) // Returns "10,772.082074"

Could I have a

humanize.Commaf(10772.08207, 2) // Returns "10,772.08"

?

Or do you suggest an alternative way to round the number, before humanize'ng? Thanks.

Allow to skip trailing zeros in FormatFloat

I like to format 123.123 and 123.1234 to with "up to 4" digits after the comma.
But using the format #.#### would result in 123.1230 for the first case instead of 123.123

Could we have something like #,#### = fill trailing zeros and #,**** skip trailing zeros? That would be backwards compatible. Or is there any formatting guideline that you are following?

Tag releases to support go.mod semantic versioning

Seems like this has been an issue before, but I wanted to bring it to attention again. I am using go.mod and since you have a release submitted on the repo, it defaults to semantic versioning which defaults to the v1.0.0 release of go-humanize which is over 2 years old. Some of my projects have been using your old release for quite some time. Please tag releases :)

Base 2 byte sizes

It would be nice to have the option to turn 1K into 1024, and 1M into 1024*1024 (and so on) instead of the straight base10 conversion that exists.

Added `ComputeBytes` and `ComputeIBytes`

I'd like to use go-humanize with testing.B to report some size.

testing.B.ReportMetrics takes a number and a suffix where such a function is already provided for SI with ComputeSI. So I added similar functions for Bytes and Bytes.

I've created a PR here adding this support: #88

Allow to skip trailing spaces in humanize.RelTime

This is a bit similar to #68, but related to time.

I would love to print something like this:

Your premium subscription expires in 3 weeks.

Trying this one:

fmt.Printf("Your premium subscription expires in %v.\n", username, humanize.RelTime(premiumExpiration, time.Now(), "", ""))

But that becomes:

Your premium subscription expires in 3 weeks .

The reason seem to be the defaultMagnitudes, which are:

var defaultMagnitudes = []RelTimeMagnitude{
	{time.Second, "now", time.Second},
	// ...
	{Month, "%d weeks %s", Week},
	// ...
	{math.MaxInt64, "a long while %s", 1},
}

Do you think it makes sense to change this so that when the blbl parameter is empty, the space is automatically removed?

TestPast has an erroneous case

--- FAIL: TestPast (0.00 seconds)
        times_test.go:10: Expected 3 month ago, got 3 months ago
FAIL
FAIL    github.com/dustin/go-humanize   0.015s

Represent sizes as int64 instead of uint64

I think this package should accept and return sizes typed int64 instead of uint64.

The standard library uses int64 to represent sizes, so I do a lot of casting when using this package.

Thanks.

Allow user to define custom time format

I'm using go-humanize to format time. But it seems output like '12 seconds ago' is too long for me. So I'm thinking if we can allow users to customize their own output format?

[Feature Request] Support localization in Time

I had a use case where I wanted to use the humanize.Time() method, but since it did not had localization support, I couldn't use it.

It would really be a nice feature to have.

I can also help in implementing it.

Bytes returns 32 MB for 31450000 bytes instead of 31 MB

Sample program

package main

import (
	"fmt"
	"github.com/dustin/go-humanize"
)

func main() {
	fmt.Println(humanize.Bytes(31350000))
	fmt.Println(humanize.Bytes(31450000))
}

Current output

The above program, compiled with the latest main branch prints 31 MB and 32 MB.

Expected output

The result should be 31 MB for both calls. This is because 31.45 is less than 31.5. Hence, should be rounded down.
This could be happening because of rounding errors in floating points.

Also, as a side note, the default rounding behaviour of the Bytes function is not documented properly.

Parse sizes

Something to turn a size string back into a number.

Option to force sub-whole digits for whole inputs

Hi,

I am using go-humanize for some backend code and BenjaminVanRyseghem/numbro for frontend code. Unfortunately, these libraries have slightly different semantics when humanizing numbers, resulting in different reports depending on where data is processed.

For example, go-humanize always omits sub-whole digits when applying SIWithDigits(input, 1, units), while numbro(input).format('0.0a') always keeps sub-hole digits.

BenjaminVanRyseghem/numbro#434

I have asked numbro to make trailing .0 optional in the output. That would at least match how go-humanize behaves.

Meanwhile, it would also be helpful for go-humanize to provide an option to keep sub-hole digits in SI text, as another way to get these libraries working in sync.

Monetary Abbreviations (Proposal)

I would like to see functionality for monetary abbreviation.

For example, an application I wrote recently integrates with a game I play. It displays in game currency with abbreviations. $1,000,000 becomes $1m, $150,899 becomes $150.9k, etc.

I already have an implementation that I made, so I was wondering if this functionality would be welcome in this project.

Support for angles?

What about adding support for angles:

  • DPS: from decimal to ° ' "
  • HMS: from decimal to H M S

tag a release

go-humanize is a great project that a lot of go projects depend on. Do you mind to tag a release to make it easier to vendor? Thank you!

Comma should be Thousands separator

You already took the time to put English pluralization in its own folder, it seems to make it more possible to internationalize. So you should also move away from calling it commas for "Thousands Separator", because many countries use "." not comma. Basically it is flipped. You don't have to internationalize yet but it would be much more clear for an international audience if you used the term Thousands Separator over commas.

count time delta

"x ago" is great, but i would like to count elapsed time, more like "4 hours, 3 minutes and 2 seconds". is this something this package should be doing?

Error while installing package

When i try to get the package via go get github.com/dustin/go-humanize then there will be an error

# github.com/dustin/go-humanize
../../dustin/go-humanize/comma.go:105: undefined: big.Float

I am on an ubuntu trusty machine with golang packages installed via apt.

Reverse humanize

Maybe I missed it in the examples, but it would be useful to be able to convert in the reverse direction as well.

"8MiB" -> 8388608
"5MB" -> 5000000

etc.

Add simple English-language string manipulation functions (e.g., PluralWord)

I would like to add some simple English-language output functions to this library, e.g.,

func Plural(quantity int, singular, plural string) string
//  Plural(1, "foo", "foos") ==> "1 foo"
//  Plural(2, "foo", "foos") ==> "2 foos"
//  Plural(2, "foo", "") ==> "2 foos"  (simple default pluralization)
func WordSeries(words []string, conjunction string) string
// WordSeries([]string{"foo", "bar"}, "and") ==> "foo and bar"
//  WordSeries([]string{"foo", "bar", "qux"}, "and") ==> "foo, bar and qux"

These aren't really in-scope for the current version of the library, but are broadly useful in similar situations (e.g., user/debugging output) and seem like a kind of "humanization".

I can contribute and maintain these functions if you are willing to accept a PR.

Add support for durations.

To change something like this:

354h22m3.24s // :S

Into something like this:

2 weeks 18 hours 22 minutes 3 seconds

or various breakdowns like minutes or just hours.

Handle MinInt64 correctly

Great library!

Comma(math.MinInt64) is not handled properly. Please add the following before the sign := "" line:

        // we need to handle MinInt64 separately
        if v == math.MinInt64 {
                return "-9,223,372,036,854,775,808"
        }

FormatFloat() overflow bug on 32bit systems

I ran into a bug tonight compiling a 32bit version and found FormatFloat() was overflowing an int somewhere. My program is dealing with nanosecond time calculations and I'm humanizing a scaling factor.

Interestingly enough, Commaf() doesn't have the same problem.

package main
import (
	"fmt"
	"math"
	"github.com/dustin/go-humanize"
)

func main() {
	var a float64 = 52746220055.92342
	fmt.Println(math.MaxFloat64)
	fmt.Println(humanize.Commaf(a))
	fmt.Println(">>> " + humanize.FormatFloat("#,###.##", a))
}
#64bit
$ go run main.go
1.7976931348623157e+308
52,746,220,055.92342
>>> 52,746,220,055.92

#32bit
$ GOARCH=386 go run main.go
1.7976931348623157e+308
52,746,220,055.92342
>>> -2,147,483,648.92

Support for Bits

Hey, humanize supports Bytes, but it would be quite nice if it also supported Bits.

The major difference is just in the capitalization. Specifically instead of 8MB it would be 8Mb.

Support humanizing durations

The time support is missing support for humanizing durations into regular units: i.e. a duration of some huge number of nanoseconds should be able to be converted into "X years, 21 days, 14 hours, 31 seconds".

While there's a huge range of variability here, IMO the most common case of durations is the simple "group by the next largest unit" aspect.

Add weight & distance

It would be nice to add weight & distance & unit support :

distance := humanize.ParseDistance("10mi", humanize.USUnits) // converts to metric system
humanize.Distance(distance, humanize.SIUnits) // Same as humanize.SI(distance, "m")
humanize.Distance(distance, humanize.USUnits) // returns "10mi"

IBytes returns 4.9GiB for 5248122880 bytes instead of 5GiB

Sample program

package main

import (
        "fmt"
        humanize "github.com/dustin/go-humanize"
)

func main() {
        fmt.Println(humanize.IBytes(5248122880))
}

Current behaviour

The above sample program compiled with master branch at commit-id 259d2a102b871d17f30e3cd9881a642961a1e486 gives 4.9 GiB.

Expected behaviour

The result should be 5 GiB.

Comma() with an uint64

Before I set off to write CommaU(v uint64) and possibly reinvent the wheel. Is it recommended to covert to a big.Int and call BigComma() ? I've not worked with the math/big library, so I'm not 100% sure.

Add percents

so "10%" or "10 %" or "10 percent" would parse into 0.1 float
and vice versa
(sorry did not add description right away)

money notation

In metric, you'd use M (mega) for million, G (giga) for billion and T (tera) for trillion.

In finance I have seen million, billion, and trillion abbreviated as M, B, and T respectively, although there doesn't seem to be a rule about it, only a best practice used in finance.

Would you allow me to add a pull request with this feature?

e.g.

humanize.Finance(2,475,260,494,216) outputs: $2.47T
humanize.Finance(2,475,260,494) outputs: $2.47B
humanize.Finance(2,475,260) outputs: $2.47M
humanize.Finance(2,475) outputs: $2.47K

NB: I added commas to make the numbers readable.

How to adjust precision of Commaf

humanize.Commaf(float64(1.1234567890), 2)
strconv.FormatFloat has a precision, just add and int like:
since you can not overload you could copy the func and rename it Commafp
that way it does not break.
Also noted that this is not localized; not that hard to localize the comma and period.

func Commafp(v float64, prec int) string {
...
parts := strings.Split(strconv.FormatFloat(v, 'f', prec, 64), ".")

Update: This does the same thing: CommafWithDigits

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.