github.com/starshine-sys/bcr@v0.21.0/format_time.go (about)

     1  package bcr
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  )
     7  
     8  // This entire file is yoinked straight from
     9  // https://github.com/jonas747/yagpdb/blob/3811b434db38ae154dc102b0c8f2dde1fd56b4d9/common/util.go#L85-L186
    10  
    11  // DurationFormatPrecision ...
    12  type DurationFormatPrecision int
    13  
    14  // ...
    15  const (
    16  	DurationPrecisionSeconds DurationFormatPrecision = iota
    17  	DurationPrecisionMinutes
    18  	DurationPrecisionHours
    19  	DurationPrecisionDays
    20  	DurationPrecisionWeeks
    21  	DurationPrecisionYears
    22  )
    23  
    24  func (d DurationFormatPrecision) String() string {
    25  	switch d {
    26  	case DurationPrecisionSeconds:
    27  		return "second"
    28  	case DurationPrecisionMinutes:
    29  		return "minute"
    30  	case DurationPrecisionHours:
    31  		return "hour"
    32  	case DurationPrecisionDays:
    33  		return "day"
    34  	case DurationPrecisionWeeks:
    35  		return "week"
    36  	case DurationPrecisionYears:
    37  		return "year"
    38  	}
    39  	return "Unknown"
    40  }
    41  
    42  // FromSeconds ...
    43  func (d DurationFormatPrecision) FromSeconds(in int64) int64 {
    44  	switch d {
    45  	case DurationPrecisionSeconds:
    46  		return in % 60
    47  	case DurationPrecisionMinutes:
    48  		return (in / 60) % 60
    49  	case DurationPrecisionHours:
    50  		return ((in / 60) / 60) % 24
    51  	case DurationPrecisionDays:
    52  		return (((in / 60) / 60) / 24) % 7
    53  	case DurationPrecisionWeeks:
    54  		// There's 52 weeks + 1 day per year (techically +1.25... but were doing +1)
    55  		// Make sure 364 days isnt 0 weeks and 0 years
    56  		days := (((in / 60) / 60) / 24) % 365
    57  		return days / 7
    58  	case DurationPrecisionYears:
    59  		return (((in / 60) / 60) / 24) / 365
    60  	}
    61  
    62  	panic("We shouldn't be here")
    63  }
    64  
    65  func pluralize(val int64) string {
    66  	if val == 1 {
    67  		return ""
    68  	}
    69  	return "s"
    70  }
    71  
    72  // HumanizeDuration ...
    73  func HumanizeDuration(precision DurationFormatPrecision, in time.Duration) string {
    74  	seconds := int64(in.Seconds())
    75  
    76  	out := make([]string, 0)
    77  
    78  	for i := int(precision); i < int(DurationPrecisionYears)+1; i++ {
    79  		curPrec := DurationFormatPrecision(i)
    80  		units := curPrec.FromSeconds(seconds)
    81  		if units > 0 {
    82  			out = append(out, fmt.Sprintf("%d %s%s", units, curPrec.String(), pluralize(units)))
    83  		}
    84  	}
    85  
    86  	outStr := ""
    87  
    88  	for i := len(out) - 1; i >= 0; i-- {
    89  		if i == 0 && i != len(out)-1 {
    90  			outStr += " and "
    91  		} else if i != len(out)-1 {
    92  			outStr += " "
    93  		}
    94  		outStr += out[i]
    95  	}
    96  
    97  	if outStr == "" {
    98  		outStr = "less than 1 " + precision.String()
    99  	}
   100  
   101  	return outStr
   102  }
   103  
   104  // HumanizeTime ...
   105  func HumanizeTime(precision DurationFormatPrecision, in time.Time) string {
   106  
   107  	now := time.Now()
   108  	if now.After(in) {
   109  		duration := now.Sub(in)
   110  		return HumanizeDuration(precision, duration) + " ago"
   111  	}
   112  	duration := in.Sub(now)
   113  	return "in " + HumanizeDuration(precision, duration)
   114  }