Go Humans! (formatters for units to human friendly sizes)

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
Comments
  • Allow custom defined time format.

    Allow custom defined time format.

    Closes: #25

    Add a new func to allow user to customize units and output format.

    eg. Users can use something like '12s ago' or '21 days later' (skipped the 'week' unit).

  • Allow user to define custom time format

    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?

  • Fix off by one error in RelTime

    Fix off by one error in RelTime

    This change fixes a user reported issue where the RelTime formatter picks the wrong magnitude at the exact nanosecond it changes.

    User report:

    package main
    
    import (
    	"fmt"
    	"time"
    
    	"google3/base/go/google"
    	"google3/third_party/golang/humanize/humanize"
    )
    
    func main() {
    	google.Init()
    	fmt.Println(humanize.RelTime(time.Unix(0, 0), time.Unix(7*24*60*60, 0), "ago", ""))
    	fmt.Println(humanize.RelTime(time.Unix(0, 0), time.Unix(7*24*60*60, 1), "ago", ""))
    	fmt.Println(humanize.RelTime(time.Unix(0, 0), time.Unix(14*24*60*60, 0), "ago", ""))
    	fmt.Println(humanize.RelTime(time.Unix(0, 0), time.Unix(14*24*60*60, 1), "ago", ""))
    }
    

    produces the following output:

    7 days ago
    1 week ago
    1 week ago
    2 weeks ago
    
  • I modified the time functions to be a bit more accurate.

    I modified the time functions to be a bit more accurate.

    Added an AccurateTime function that returns strings like 2 years, 8 months.

    Added a RelTimeMagnitude that implements this with configurable number of descending magnitudes.

    Broke some fuzzy time in the 1 Year and higher range. This one confused me a bit, I'm not sure what the intent was but it didn't make any sense to me.

    I also cleaned up the RelTime function, taking that loop that iterated over the format string trying to build an argument list. It was kind of convoluted and as every case was exactly the same after I removed the %s from each (adding the "ago" later) so I just added a flag and a single parameter to Sprintf.

    I made "now" a special case because it was simpler to do that.

    I think I left a broken test or two in your tests, having to do with the fuzzy "years" ranges. Didn't know what to do about that and my tests could certainly be more comprehensive.

  • Feature format number

    Feature format number

    This has been useful in a number of projects and I think go-humanize is a suitable home.

    See examples here http://play.golang.org/p/LXc1Ddm1lJ Much thanks to @gorhill for original code :+1:

  • Add i18n to go-humanize

    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"
    
  • Adds package humanize/english for English-word manipulations.

    Adds package humanize/english for English-word manipulations.

    Includes:

    • Plural and PluralWord to form simple plurals.
    • WordSeries and OxfordWordSeries to form comma-separated lists (e.g., "foo, bar and baz").

    Fixes: #57

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

    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.

  • Space between numerical value and unit symbol for SI output

    Space between numerical value and unit symbol for SI output

    Very nice collection here. Just a niggle - SI convention calls for a space between the number and the unit: 1 m, 10 kg, 123 mS ... etc

    http://physics.nist.gov/Pubs/SP811/sec07.html

  • Represent sizes as int64 instead of uint64

    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.

  • Make it compatible again with go < 1.5

    Make it compatible again with go < 1.5

    Since https://github.com/dustin/go-humanize/commit/c447c0d5900e8b1bea327c219fa5d3cba45ba234, go-humanize is not compatibly anymore with Go <1.5. I know, it's an old version, but right now I'm still stuck with it :(

    This fixes it, while keeping the feature for more up-to-date versions.

  • Lost zeros using SIWithDigits with 0 decimals 200.0 becomes

    Lost zeros using SIWithDigits with 0 decimals 200.0 becomes "2"

    Hi, I have noticed that the function humanize.SIWithDigits doesn't handle when the value to be rounded doesn't have any decimals.

    Example: fmt.Printf("20 -> %s\n", humanize.SIWithDigits(20.0, 0, "Unit")) fmt.Printf("200 -> %s\n", humanize.SIWithDigits(200.0, 0, "Unit"))

    Output: 20 -> 2 Unit 200 -> 2 Unit

    I think the function stripTrailingZeros needs to check if "." is in the string at all

    Workaround for now it to not use 0 decimals

  • Force to show decimal in CommafWithDigits

    Force to show decimal in CommafWithDigits

    My float64 number is 1000.00

    Actual: CommafWithDigits(1000.00, 2) => 1,000

    Expect: CommafWithDigits(1000.00, 2) => 1,000.00

    When inputting a decimal like 2 it should have xxxx.xx

  • How to convert decimal to million or billion formats?

    How to convert decimal to million or billion formats?

    I want to convert decimal numbers like 1000 to 1k, 10000 to 10k, and 100000 to 100k and so on. But I'm a little confused, how to do it? Is there any function available or implemented yet about this theory?

  • Bytes returns 32 MB for 31450000 bytes instead of 31 MB

    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.

  • Comma() is 2.5 faster now

    Comma() is 2.5 faster now

    Hi there!

    Decided to leetcode Comma(). The result is in this PR. Managed to get rid of 4 allocations, removed 2 dependencies and reduced the execution time.

    goos: darwin
    goarch: arm64
    pkg: github.com/kaatinga/krendel
    BenchmarkComma
    BenchmarkComma-8          	 5709186	       207.5 ns/op	      50 B/op	       8 allocs/op
    BenchmarkInt64_String
    BenchmarkInt64_String-8   	13717701	        86.55 ns/op	      64 B/op	       4 allocs/op
    PASS
    
[Crawler/Scraper for Golang]🕷A lightweight distributed friendly Golang crawler framework.一个轻量的分布式友好的 Golang 爬虫框架。

Goribot 一个分布式友好的轻量的 Golang 爬虫框架。 完整文档 | Document !! Warning !! Goribot 已经被迁移到 Gospider|github.com/zhshch2002/gospider。修复了一些调度问题并分离了网络请求部分到另一个仓库。此仓库会继续

Oct 29, 2022
URL-friendly slugify with multiple languages support.

slug Package slug generate slug from unicode string, URL-friendly slugify with multiple languages support. Documentation online Example package main

Jan 4, 2023
Go Humans! (formatters for units to human friendly sizes)

Humane Units 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

Jan 2, 2023
lsp is like ls command but more human-friendly
lsp is like ls command but more human-friendly

lsp: list files in a mildly human-frendlier manner lsp lists files, like ls command, but it does not attempt to meet that archaic POSIX specification,

Dec 12, 2022
Human-friendly Go module that builds and prints directory trees using ASCII art

Human-friendly Go module that builds and prints directory trees using ASCII art.

Oct 11, 2022
Simple and configurable Logging in Go, with level, formatters and writers

go-log Logging package similar to log4j for the Golang. Support dynamic log level Support customized formatter TextFormatter JSONFormatter Support mul

Sep 26, 2022
Copy of stdlib's time.Duration, but ParseDuration accepts other bigger units such as days, weeks, months and years

duration Copy of stdlib's time.Duration, but ParseDuration accepts other units as well: d: days (7 * 24 * time.Hour) w: weeks (7 * Day) mo: months (30

Jun 21, 2022
tool for working with numbers and units

tool for working with numbers and units

Nov 26, 2022
smartcrop finds good image crops for arbitrary crop sizes
smartcrop finds good image crops for arbitrary crop sizes

smartcrop smartcrop finds good image crops for arbitrary sizes. It is a pure Go implementation, based on Jonas Wagner's smartcrop.js Image: https://ww

Jan 8, 2023
Automatically compress podcasts to tiny file sizes for bandwidth constrained devices like cellular.
Automatically compress podcasts to tiny file sizes for bandwidth constrained devices like cellular.

tinycast Automatically compress podcasts to tiny file sizes for bandwidth constrained connections like cellular or satellite.

Sep 18, 2022
Visualizer of container layer sizes
Visualizer of container layer sizes

Container Layer Analyzer Have you ever wondered what exactly is eating up your precious space in each layer of your container images? Would you like t

Dec 21, 2022
Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket

Features Resize upladed images to s3 bucket with given sizes, and uploades new images back to bucket Environment Variables IMAGE_SIZES - formax 200x20

Feb 2, 2022
copy files for humans

Go-Decent-Copy go-decent-copy provides a copy file for humans Usage package main import "github.com/hugocarreira/go-decent-copy" func main() { e

Sep 26, 2022
Golang beautify data display for Humans

Golang beautify data display for Humans English 简体中文 Install # Stable version go get -u -v gopkg.in/ffmt.v1 # Latest version go get -u -v github.com/

Dec 22, 2022
🐶 Command-line DNS Client for Humans. Written in Golang
🐶 Command-line DNS Client for Humans. Written in Golang

doggo ?? Command-line DNS client for humans doggo is a modern command-line DNS client (like dig) written in Golang. It outputs information in a neat c

Dec 29, 2022
automated "fork" of gVisor that only contains the netstack bits so the go.mod is smaller. maintained by scripts, not humans.

netstack This is a "fork" of https://github.com/google/gvisor, extracting out just the "netstack" networking bits, which previously were self-containe

Nov 24, 2022
Golang beautify data display for Humans

Golang beautify data display for Humans English 简体中文 Usage Examples package main import ( ffmt "gopkg.in/ffmt.v1" ) func main() { example() } typ

Dec 22, 2022
HuJSON: JSON for Humans (comments and trailing commas)

HuJSON - Human JSON The HuJSON decoder is a JSON decoder that also allows comments, both /* ... */ and // to end of line trailing commas on arrays and

Dec 22, 2022
'go test' runner with output optimized for humans, JUnit XML for CI integration, and a summary of the test results.
'go test' runner with output optimized for humans, JUnit XML for CI integration, and a summary of the test results.

gotestsum gotestsum runs tests using go test --json, prints formatted test output, and a summary of the test run. It is designed to work well for both

Dec 28, 2022
Typo/error resilient, human-readable token generator

toktok A human-friendly token generator Creates tokens which avoid characters that can be easily misinterpreted, like '1' and 'I' or '8' and 'B', as w

Sep 16, 2022