time_range.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package tsdb
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "time"
  7. )
  8. func NewTimeRange(from, to string) *TimeRange {
  9. return &TimeRange{
  10. From: from,
  11. To: to,
  12. now: time.Now(),
  13. }
  14. }
  15. func NewFakeTimeRange(from, to string, now time.Time) *TimeRange {
  16. return &TimeRange{
  17. From: from,
  18. To: to,
  19. now: now,
  20. }
  21. }
  22. type TimeRange struct {
  23. From string
  24. To string
  25. now time.Time
  26. }
  27. func (tr *TimeRange) GetFromAsMsEpoch() int64 {
  28. return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
  29. }
  30. func (tr *TimeRange) GetFromAsSecondsEpoch() int64 {
  31. return tr.GetFromAsMsEpoch() / 1000
  32. }
  33. func (tr *TimeRange) GetFromAsTimeUTC() time.Time {
  34. return tr.MustGetFrom().UTC()
  35. }
  36. func (tr *TimeRange) GetToAsMsEpoch() int64 {
  37. return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
  38. }
  39. func (tr *TimeRange) GetToAsSecondsEpoch() int64 {
  40. return tr.GetToAsMsEpoch() / 1000
  41. }
  42. func (tr *TimeRange) GetToAsTimeUTC() time.Time {
  43. return tr.MustGetTo().UTC()
  44. }
  45. func (tr *TimeRange) MustGetFrom() time.Time {
  46. if res, err := tr.ParseFrom(); err != nil {
  47. return time.Unix(0, 0)
  48. } else {
  49. return res
  50. }
  51. }
  52. func (tr *TimeRange) MustGetTo() time.Time {
  53. if res, err := tr.ParseTo(); err != nil {
  54. return time.Unix(0, 0)
  55. } else {
  56. return res
  57. }
  58. }
  59. func tryParseUnixMsEpoch(val string) (time.Time, bool) {
  60. if val, err := strconv.ParseInt(val, 10, 64); err == nil {
  61. seconds := val / 1000
  62. nano := (val - seconds*1000) * 1000000
  63. return time.Unix(seconds, nano), true
  64. }
  65. return time.Time{}, false
  66. }
  67. func (tr *TimeRange) ParseFrom() (time.Time, error) {
  68. if res, ok := tryParseUnixMsEpoch(tr.From); ok {
  69. return res, nil
  70. }
  71. fromRaw := strings.Replace(tr.From, "now-", "", 1)
  72. diff, err := time.ParseDuration("-" + fromRaw)
  73. if err != nil {
  74. return time.Time{}, err
  75. }
  76. return tr.now.Add(diff), nil
  77. }
  78. func (tr *TimeRange) ParseTo() (time.Time, error) {
  79. if tr.To == "now" {
  80. return tr.now, nil
  81. } else if strings.HasPrefix(tr.To, "now-") {
  82. withoutNow := strings.Replace(tr.To, "now-", "", 1)
  83. diff, err := time.ParseDuration("-" + withoutNow)
  84. if err != nil {
  85. return time.Time{}, nil
  86. }
  87. return tr.now.Add(diff), nil
  88. }
  89. if res, ok := tryParseUnixMsEpoch(tr.To); ok {
  90. return res, nil
  91. }
  92. return time.Time{}, fmt.Errorf("cannot parse to value %s", tr.To)
  93. }
  94. // EpochPrecisionToMs converts epoch precision to millisecond, if needed.
  95. // Only seconds to milliseconds supported right now
  96. func EpochPrecisionToMs(value float64) float64 {
  97. s := strconv.FormatFloat(value, 'e', -1, 64)
  98. if strings.HasSuffix(s, "e+09") {
  99. return value * float64(1e3)
  100. }
  101. if strings.HasSuffix(s, "e+18") {
  102. return value / float64(time.Millisecond)
  103. }
  104. return value
  105. }