github.com/mithrandie/csvq@v1.18.1/lib/option/static.go (about)

     1  package option
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  var (
    11  	TestTime  time.Time // For Tests
    12  	Timezones = NewTimezoneMap()
    13  
    14  	random  *rand.Rand
    15  	getRand sync.Once
    16  )
    17  
    18  func GetRand() *rand.Rand {
    19  	getRand.Do(func() {
    20  		random = rand.New(rand.NewSource(time.Now().UnixNano()))
    21  	})
    22  	return random
    23  }
    24  
    25  func GetLocation(timezone string) (*time.Location, error) {
    26  	return Timezones.Get(timezone)
    27  }
    28  
    29  func Now(location *time.Location) time.Time {
    30  	if !TestTime.IsZero() {
    31  		return TestTime
    32  	}
    33  	return time.Now().In(location)
    34  }
    35  
    36  type TimezoneMap struct {
    37  	m   *sync.Map
    38  	mtx *sync.Mutex
    39  }
    40  
    41  func NewTimezoneMap() TimezoneMap {
    42  	return TimezoneMap{
    43  		m:   &sync.Map{},
    44  		mtx: &sync.Mutex{},
    45  	}
    46  }
    47  
    48  func (tzmap TimezoneMap) store(key string, value *time.Location) {
    49  	tzmap.m.Store(key, value)
    50  }
    51  
    52  func (tzmap TimezoneMap) load(key string) (*time.Location, bool) {
    53  	v, ok := tzmap.m.Load(key)
    54  	if ok {
    55  		return v.(*time.Location), ok
    56  	}
    57  	return nil, ok
    58  }
    59  
    60  func (tzmap TimezoneMap) Get(timezone string) (*time.Location, error) {
    61  	if v, ok := tzmap.load(timezone); ok {
    62  		return v, nil
    63  	}
    64  
    65  	tzmap.mtx.Lock()
    66  	defer tzmap.mtx.Unlock()
    67  
    68  	if v, ok := tzmap.load(timezone); ok {
    69  		return v, nil
    70  	}
    71  
    72  	l, err := time.LoadLocation(timezone)
    73  	if err != nil {
    74  		return nil, fmt.Errorf("timezone %q does not exist", timezone)
    75  	}
    76  
    77  	tzmap.store(timezone, l)
    78  	return l, nil
    79  }