github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/datetime/unit.go (about)

     1  package datetime
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // Unit specifies an unit of time (Millisecond, Second...).
    11  type Unit int
    12  
    13  const (
    14  	Millisecond Unit = iota
    15  	Second
    16  	Minute
    17  	Hour
    18  	Day
    19  	Week
    20  	Month
    21  	Year
    22  )
    23  
    24  var nanoseconds = []float64{
    25  	1e6,
    26  	1e9,
    27  	6e10,
    28  	36e11,
    29  	864e11,
    30  	6048e11,
    31  	26784e11,
    32  	31536e12,
    33  }
    34  
    35  // Nanosecond returns representation of an Unit
    36  // in nanosconds
    37  func (u Unit) Nanosecond() float64 {
    38  	return nanoseconds[u]
    39  }
    40  
    41  // IsDatesEqual check if two partial dates match.
    42  // This case the day means not the amount of days in Time,
    43  // but the day of the month.
    44  // The same rules applied to each unit.
    45  func IsDatesEqual(tm1, tm2 time.Time, u Unit) bool {
    46  	switch u {
    47  	case Millisecond:
    48  		tm1Msec := tm1.Nanosecond() / 1e6
    49  		tm2Msec := tm2.Nanosecond() / 1e6
    50  		return tm1Msec == tm2Msec
    51  	case Second:
    52  		return tm1.Second() == tm2.Second()
    53  	case Minute:
    54  		return tm1.Minute() == tm2.Minute()
    55  	case Hour:
    56  		return tm1.Hour() == tm2.Hour()
    57  	case Day:
    58  		return tm1.Day() == tm2.Day()
    59  	case Week:
    60  		tm1Wk := tm1.Day() / 7
    61  		tm2Wk := tm2.Day() / 7
    62  		return tm1Wk == tm2Wk
    63  	case Month:
    64  		return tm1.Month() == tm2.Month()
    65  	case Year:
    66  		return tm1.Year() == tm2.Year()
    67  	}
    68  	return false
    69  }
    70  
    71  // AddUnit add amount given in u to tm
    72  func AddUnit(tm time.Time, amount int, u Unit) (res time.Time) {
    73  	if u < Day {
    74  		return tm.Add(time.Duration(amount) * time.Duration(int64(u.Nanosecond())))
    75  	}
    76  
    77  	switch u {
    78  	case Day:
    79  		res = tm.AddDate(0, 0, amount*1)
    80  	case Week:
    81  		res = tm.AddDate(0, 0, amount*7)
    82  	case Month:
    83  		res = tm.AddDate(0, amount*1, 0)
    84  	case Year:
    85  		res = tm.AddDate(amount*1, 0, 0)
    86  	}
    87  
    88  	return
    89  }
    90  
    91  // UnitFromString returns true and an Unit object if
    92  // Unit with that name exists. Returns false, otherwise.
    93  func UnitFromString(s string) (Unit, error) {
    94  	switch strings.ToLower(s) {
    95  	case "y", "year", "years":
    96  		return Year, nil
    97  	case "m", "month", "months":
    98  		return Month, nil
    99  	case "w", "week", "weeks":
   100  		return Week, nil
   101  	case "d", "day", "days":
   102  		return Day, nil
   103  	case "h", "hour", "hours":
   104  		return Hour, nil
   105  	case "i", "minute", "minutes":
   106  		return Minute, nil
   107  	case "s", "second", "seconds":
   108  		return Second, nil
   109  	case "f", "millisecond", "milliseconds":
   110  		return Millisecond, nil
   111  	}
   112  	return -1, errors.Errorf("no such unit '%s'", s)
   113  }