time_range.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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) GetToAsMsEpoch() int64 {
  34. return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
  35. }
  36. func (tr *TimeRange) GetToAsSecondsEpoch() int64 {
  37. return tr.GetToAsMsEpoch() / 1000
  38. }
  39. func (tr *TimeRange) MustGetFrom() time.Time {
  40. if res, err := tr.ParseFrom(); err != nil {
  41. return time.Unix(0, 0)
  42. } else {
  43. return res
  44. }
  45. }
  46. func (tr *TimeRange) MustGetTo() time.Time {
  47. if res, err := tr.ParseTo(); err != nil {
  48. return time.Unix(0, 0)
  49. } else {
  50. return res
  51. }
  52. }
  53. func tryParseUnixMsEpoch(val string) (time.Time, bool) {
  54. if val, err := strconv.ParseInt(val, 10, 64); err == nil {
  55. seconds := val / 1000
  56. nano := (val - seconds*1000) * 1000000
  57. return time.Unix(seconds, nano), true
  58. }
  59. return time.Time{}, false
  60. }
  61. func (tr *TimeRange) ParseFrom() (time.Time, error) {
  62. if res, ok := tryParseUnixMsEpoch(tr.From); ok {
  63. return res, nil
  64. }
  65. fromRaw := strings.Replace(tr.From, "now-", "", 1)
  66. diff, err := time.ParseDuration("-" + fromRaw)
  67. if err != nil {
  68. return time.Time{}, err
  69. }
  70. return tr.now.Add(diff), nil
  71. }
  72. func (tr *TimeRange) ParseTo() (time.Time, error) {
  73. if tr.To == "now" {
  74. return tr.now, nil
  75. } else if strings.HasPrefix(tr.To, "now-") {
  76. withoutNow := strings.Replace(tr.To, "now-", "", 1)
  77. diff, err := time.ParseDuration("-" + withoutNow)
  78. if err != nil {
  79. return time.Time{}, nil
  80. }
  81. return tr.now.Add(diff), nil
  82. }
  83. if res, ok := tryParseUnixMsEpoch(tr.To); ok {
  84. return res, nil
  85. }
  86. return time.Time{}, fmt.Errorf("cannot parse to value %s", tr.To)
  87. }
  88. // EpochPrecisionToMs converts epoch precision to millisecond, if needed.
  89. // Only seconds to milliseconds supported right now
  90. func EpochPrecisionToMs(value float64) float64 {
  91. if int64(value)/1e10 == 0 {
  92. return float64(value * 1e3)
  93. }
  94. return float64(value)
  95. }