github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/cmn/cos/time_utils.go (about)

     1  // Package cos provides common low-level types and utilities for all aistore projects
     2  /*
     3   * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved.
     4   */
     5  package cos
     6  
     7  import (
     8  	"fmt"
     9  	"strconv"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/NVIDIA/aistore/cmn/debug"
    14  )
    15  
    16  // in addition to standard layouts at /usr/local/go/src/time/format.go
    17  const (
    18  	StampMicro = "15:04:05.000000" // time.StampMicro without a date
    19  	StampSec   = "15:04:05"        // time.Stamp without a date
    20  
    21  	// S3 ListObjectsV2
    22  	// https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html
    23  	ISO8601 = "2006-01-02T15:04:05.000Z"
    24  
    25  	// S3 HeadObject
    26  	// https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html#API_HeadObject_Examples
    27  	RFC1123GMT = "Mon, 17 Dec 2012 02:14:10 GMT"
    28  )
    29  
    30  // `unixnano` here is expected to be "nanoseconds since January 1, 1970 UTC"
    31  func FormatNanoTime(unixnano int64, format string) string {
    32  	t := time.Unix(0, unixnano)
    33  	return FormatTime(t, format)
    34  }
    35  
    36  func FormatTime(t time.Time, format string) string {
    37  	switch format {
    38  	case "", time.RFC822:
    39  		return t.Format(time.RFC822) // default
    40  	case RFC1123GMT:
    41  		s := t.UTC().Format(time.RFC1123)
    42  		debug.Assert(strings.HasSuffix(s, "UTC"), s)
    43  		return strings.TrimSuffix(s, "UTC") + "GMT"
    44  	default:
    45  		return t.Format(format)
    46  	}
    47  }
    48  
    49  func FormatNowStamp() string { return FormatTime(time.Now(), StampMicro) }
    50  
    51  func S2Duration(s string) (time.Duration, error) {
    52  	d, err := strconv.ParseInt(s, 0, 64)
    53  	return time.Duration(d), err
    54  }
    55  
    56  func UnixNano2S(unixnano int64) string   { return strconv.FormatInt(unixnano, 10) }
    57  func S2UnixNano(s string) (int64, error) { return strconv.ParseInt(s, 10, 64) }
    58  func IsTimeZero(t time.Time) bool        { return t.IsZero() || t.UTC().Unix() == 0 } // https://github.com/golang/go/issues/33597
    59  
    60  // wait duration => probing frequency
    61  func ProbingFrequency(dur time.Duration) time.Duration {
    62  	sleep := min(dur>>3, time.Second)
    63  	sleep = max(dur>>6, sleep)
    64  	return max(sleep, 100*time.Millisecond)
    65  }
    66  
    67  // FormatMilli returns a duration formatted as milliseconds. For values bigger
    68  // than millisecond, it returns an integer number "#ms". For values smaller than
    69  // millisecond, the function returns fractional number "0.##ms"
    70  func FormatMilli(tm time.Duration) string {
    71  	milli := tm.Milliseconds()
    72  	if milli > 0 {
    73  		return fmt.Sprintf("%dms", milli)
    74  	}
    75  	micro := tm.Microseconds()
    76  	if micro == 0 {
    77  		return "0"
    78  	}
    79  	return fmt.Sprintf("%.2fms", float64(micro)/1000.0)
    80  }
    81  
    82  // access time validity; prefetch special (negative) case - sets atime=-now
    83  // 946771140000000000 = time.Parse(time.RFC3339Nano, "2000-01-01T23:59:00Z").UnixNano()
    84  func IsValidAtime(atime int64) bool {
    85  	return atime > 946771140000000000 ||
    86  		(atime < -946771140000000000 && atime != -6795364578871345152) // time.IsZero()
    87  }