github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/timeutil/time.go (about)

     1  // Copyright 2016 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package timeutil
    12  
    13  import (
    14  	"strings"
    15  	"time"
    16  )
    17  
    18  // LibPQTimePrefix is the prefix lib/pq prints time-type datatypes with.
    19  const LibPQTimePrefix = "0000-01-01"
    20  
    21  // Since returns the time elapsed since t.
    22  // It is shorthand for Now().Sub(t).
    23  func Since(t time.Time) time.Duration {
    24  	return Now().Sub(t)
    25  }
    26  
    27  // Until returns the duration until t.
    28  // It is shorthand for t.Sub(Now()).
    29  func Until(t time.Time) time.Duration {
    30  	return t.Sub(Now())
    31  }
    32  
    33  // UnixEpoch represents the Unix epoch, January 1, 1970 UTC.
    34  var UnixEpoch = time.Unix(0, 0).UTC()
    35  
    36  // FromUnixMicros returns the UTC time.Time corresponding to the given Unix
    37  // time, usec microseconds since UnixEpoch. In Go's current time.Time
    38  // implementation, all possible values for us can be represented as a time.Time.
    39  func FromUnixMicros(us int64) time.Time {
    40  	return time.Unix(us/1e6, (us%1e6)*1e3).UTC()
    41  }
    42  
    43  // ToUnixMicros returns t as the number of microseconds elapsed since UnixEpoch.
    44  // Fractional microseconds are rounded, half up, using time.Round. Similar to
    45  // time.Time.UnixNano, the result is undefined if the Unix time in microseconds
    46  // cannot be represented by an int64.
    47  func ToUnixMicros(t time.Time) int64 {
    48  	return t.Unix()*1e6 + int64(t.Round(time.Microsecond).Nanosecond())/1e3
    49  }
    50  
    51  // Unix wraps time.Unix ensuring that the result is in UTC instead of Local.
    52  func Unix(sec, nsec int64) time.Time {
    53  	return time.Unix(sec, nsec).UTC()
    54  }
    55  
    56  // SleepUntil sleeps until the given time. The current time is
    57  // refreshed every second in case there was a clock jump
    58  //
    59  // untilNanos is the target time to sleep till in epoch nanoseconds
    60  // currentTimeNanos is a function returning current time in epoch nanoseconds
    61  func SleepUntil(untilNanos int64, currentTimeNanos func() int64) {
    62  	for {
    63  		d := time.Duration(untilNanos - currentTimeNanos())
    64  		if d <= 0 {
    65  			break
    66  		}
    67  		if d > time.Second {
    68  			d = time.Second
    69  		}
    70  		time.Sleep(d)
    71  	}
    72  }
    73  
    74  // ReplaceLibPQTimePrefix replaces unparsable lib/pq dates used for timestamps
    75  // (0000-01-01) with timestamps that can be parsed by date libraries.
    76  func ReplaceLibPQTimePrefix(s string) string {
    77  	if strings.HasPrefix(s, LibPQTimePrefix) {
    78  		return "1970-01-01" + s[len(LibPQTimePrefix):]
    79  	}
    80  	return s
    81  }