package api import ( "fmt" "math" "strings" "time" ) // Internationalization (i18n) var Internationalization = map[string]map[string]string{} func init() { Internationalization["pt-BR"] = map[string]string{ "future": "em %s", "past": "%s atrás", "s": "alguns segundos", "ss": "%d segundos", "m": "um minuto", "mm": "%d minutos", "h": "uma hora", "hh": "%d horas", "d": "um dia", "dd": "%d dias", "M": "um mês", "MM": "%d meses", "y": "acerca de um ano", "yy": "%d anos", } } func repeatCount(test bool) int { if test { return 1 } else { return 2 } } // FromDuration returns a friendly string representing an approximation of the // given duration func TimeAgoFromDuration(d time.Duration, locale ...string) string { var ( loc = localeparse(locale...) seconds = int(math.Floor(d.Seconds() + .50)) templates = Internationalization[loc] minutes, hours, days, months, years int // format = func(prefix string, value int) string { id := strings.Repeat(prefix, repeatCount(value == 1)) return fmt.Sprintf( templates[id], value, ) } ) switch { case seconds < 30: return templates["s"] case seconds < 60: return templates["ss"] } if minutes = div(seconds, 60); minutes < 60 { return format("m", minutes) } if hours = div(minutes, 60); hours < 24 { return format("h", hours) } if days = div(hours, 24); days < 31 { return format("d", days) } if months = div(days, 31); months < 12 { return format("M", months) } years = div(months, 12) return format("y", years) } func localeparse(locale ...string) (loc string) { if len(locale) > 0 { loc = locale[0] } else { loc = "pt-BR" } return } // FromTime returns a friendly string representing the approximate difference // from the given time and time.Now() func TimeAgoFromTime(t time.Time, locale ...string) string { var ( loc = localeparse(locale...) now = time.Now() d time.Duration id string templates = Internationalization[loc] ) if t.Before(now) { d = now.Sub(t) id = "past" } else { d = t.Sub(now) id = "future" } return fmt.Sprintf(templates[id], TimeAgoFromDuration(d, locale...)) } func div(numerator int, denominator int) int { rem := numerator % denominator result := numerator / denominator if rem >= (denominator / 2) { result++ } return result } // func round(f float64) int { // return // } // func pluralize(i int, s string) string { // var buf bytes.Buffer // buf.WriteString(fmt.Sprintf("%d %s", i, s)) // if i != 1 { // buf.WriteString("s") // } // return buf.String() // } // type TimeAgo struct { // Locale string // templates map[string]string // } // func NewTimeAgo(locale ...string) *TimeAgo { // return &TimeAgo{ // Locale: L, // templates: Internationalization[L], // } // } // const ( // minute = 1 // hour = minute * 60 // day = hour * 24 // month = day * 30 // year = day * 365 // // quarter = year / 4 // )