time_range.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. type TimeRange struct {
  16. From string
  17. To string
  18. now time.Time
  19. }
  20. func (tr *TimeRange) GetFromAsMsEpoch() int64 {
  21. return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
  22. }
  23. func (tr *TimeRange) GetToAsMsEpoch() int64 {
  24. return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
  25. }
  26. func (tr *TimeRange) MustGetFrom() time.Time {
  27. if res, err := tr.ParseFrom(); err != nil {
  28. return time.Unix(0, 0)
  29. } else {
  30. return res
  31. }
  32. }
  33. func (tr *TimeRange) MustGetTo() time.Time {
  34. if res, err := tr.ParseTo(); err != nil {
  35. return time.Unix(0, 0)
  36. } else {
  37. return res
  38. }
  39. }
  40. func tryParseUnixMsEpoch(val string) (time.Time, bool) {
  41. if val, err := strconv.ParseInt(val, 10, 64); err == nil {
  42. seconds := val / 1000
  43. nano := (val - seconds*1000) * 1000000
  44. return time.Unix(seconds, nano), true
  45. }
  46. return time.Time{}, false
  47. }
  48. func (tr *TimeRange) ParseFrom() (time.Time, error) {
  49. if res, ok := tryParseUnixMsEpoch(tr.From); ok {
  50. return res, nil
  51. }
  52. fromRaw := strings.Replace(tr.From, "now-", "", 1)
  53. diff, err := time.ParseDuration("-" + fromRaw)
  54. if err != nil {
  55. return time.Time{}, err
  56. }
  57. return tr.now.Add(diff), nil
  58. }
  59. func (tr *TimeRange) ParseTo() (time.Time, error) {
  60. if tr.To == "now" {
  61. return tr.now, nil
  62. } else if strings.HasPrefix(tr.To, "now-") {
  63. withoutNow := strings.Replace(tr.To, "now-", "", 1)
  64. diff, err := time.ParseDuration("-" + withoutNow)
  65. if err != nil {
  66. return time.Time{}, nil
  67. }
  68. return tr.now.Add(diff), nil
  69. }
  70. if res, ok := tryParseUnixMsEpoch(tr.To); ok {
  71. return res, nil
  72. }
  73. return time.Time{}, fmt.Errorf("cannot parse to value %s", tr.To)
  74. }
  75. // EpochPrecisionToMs converts epoch precision to millisecond, if needed.
  76. // Only seconds to milliseconds supported right now
  77. func EpochPrecisionToMs(value float64) float64 {
  78. s := strconv.FormatFloat(value, 'e', -1, 64)
  79. if strings.HasSuffix(s, "e+09") {
  80. return value * float64(1e3)
  81. }
  82. if strings.HasSuffix(s, "e+18") {
  83. return value / float64(time.Millisecond)
  84. }
  85. return value
  86. }