github.com/grafana/pyroscope@v1.18.0/pkg/operations/time.go (about)

     1  package operations
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/prometheus/common/model"
    10  )
    11  
    12  func ParseTime(s string) (time.Time, error) {
    13  	if s == "" {
    14  		return time.Time{}, fmt.Errorf("empty time")
    15  	}
    16  	t, err := time.Parse(time.RFC3339, s)
    17  	if err == nil {
    18  		return t, nil
    19  	}
    20  
    21  	// try if it is a relative time
    22  	d, rerr := parseRelativeTime(s)
    23  	if rerr == nil {
    24  		return time.Now().Add(-d), nil
    25  	}
    26  
    27  	timestamp, terr := strconv.ParseInt(s, 10, 64)
    28  	if terr == nil {
    29  		/**
    30  		1689341454
    31  		1689341454046
    32  		1689341454046908
    33  		1689341454046908187
    34  		*/
    35  		switch len(s) {
    36  		case 10:
    37  			return time.Unix(timestamp, 0), nil
    38  		case 13:
    39  			return time.UnixMilli(timestamp), nil
    40  		case 16:
    41  			return time.UnixMicro(timestamp), nil
    42  		case 19:
    43  			return time.Unix(0, timestamp), nil
    44  		default:
    45  			return time.Time{}, fmt.Errorf("invalid timestamp length: %s", s)
    46  		}
    47  	}
    48  	// if not return first error
    49  	return time.Time{}, err
    50  
    51  }
    52  
    53  func parseRelativeTime(s string) (time.Duration, error) {
    54  	s = strings.TrimSpace(s)
    55  	if s == "now" {
    56  		return 0, nil
    57  	}
    58  	s = strings.TrimPrefix(s, "now-")
    59  
    60  	d, err := model.ParseDuration(s)
    61  	if err != nil {
    62  		return 0, err
    63  	}
    64  	return time.Duration(d), nil
    65  }