github.com/vipernet-xyz/tm@v0.34.24/types/time/time.go (about)

     1  package time
     2  
     3  import (
     4  	"sort"
     5  	"time"
     6  )
     7  
     8  // Now returns the current time in UTC with no monotonic component.
     9  func Now() time.Time {
    10  	return Canonical(time.Now())
    11  }
    12  
    13  // Canonical returns UTC time with no monotonic component.
    14  // Stripping the monotonic component is for time equality.
    15  // See https://github.com/vipernet-xyz/tm/pull/2203#discussion_r215064334
    16  func Canonical(t time.Time) time.Time {
    17  	return t.Round(0).UTC()
    18  }
    19  
    20  // WeightedTime for computing a median.
    21  type WeightedTime struct {
    22  	Time   time.Time
    23  	Weight int64
    24  }
    25  
    26  // NewWeightedTime with time and weight.
    27  func NewWeightedTime(time time.Time, weight int64) *WeightedTime {
    28  	return &WeightedTime{
    29  		Time:   time,
    30  		Weight: weight,
    31  	}
    32  }
    33  
    34  // WeightedMedian computes weighted median time for a given array of WeightedTime and the total voting power.
    35  func WeightedMedian(weightedTimes []*WeightedTime, totalVotingPower int64) (res time.Time) {
    36  	median := totalVotingPower / 2
    37  
    38  	sort.Slice(weightedTimes, func(i, j int) bool {
    39  		if weightedTimes[i] == nil {
    40  			return false
    41  		}
    42  		if weightedTimes[j] == nil {
    43  			return true
    44  		}
    45  		return weightedTimes[i].Time.UnixNano() < weightedTimes[j].Time.UnixNano()
    46  	})
    47  
    48  	for _, weightedTime := range weightedTimes {
    49  		if weightedTime != nil {
    50  			if median <= weightedTime.Weight {
    51  				res = weightedTime.Time
    52  				break
    53  			}
    54  			median -= weightedTime.Weight
    55  		}
    56  	}
    57  	return
    58  }