time_range.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package tsdb
  15. import (
  16. "fmt"
  17. "strconv"
  18. "strings"
  19. "time"
  20. )
  21. type TimeRange struct {
  22. From string
  23. To string
  24. now time.Time
  25. }
  26. func NewTimeRange(from, to string) *TimeRange {
  27. return &TimeRange{
  28. From: from,
  29. To: to,
  30. now: time.Now(),
  31. }
  32. }
  33. func TryParseUnixMsEpoch(val string) (time.Time, bool) {
  34. if val, err := strconv.ParseInt(val, 10, 64); err == nil {
  35. seconds := val / 1000
  36. nano := (val - seconds*1000) * 1000000
  37. return time.Unix(seconds, nano), true
  38. }
  39. return time.Time{}, false
  40. }
  41. func (tr *TimeRange) ParseFrom() (time.Time, error) {
  42. res, ok := TryParseUnixMsEpoch(tr.From)
  43. if ok {
  44. return res, nil
  45. }
  46. fromRaw := strings.Replace(tr.From, "now-", "", 1)
  47. diff, err := time.ParseDuration("-" + fromRaw)
  48. if err != nil {
  49. return time.Time{}, err
  50. }
  51. return tr.now.Add(diff), nil
  52. }
  53. func (tr *TimeRange) ParseTo() (time.Time, error) {
  54. if tr.To == "now" {
  55. return tr.now, nil
  56. } else if strings.HasPrefix(tr.To, "now-") {
  57. withoutNow := strings.Replace(tr.To, "now-", "", 1)
  58. diff, err := time.ParseDuration("-" + withoutNow)
  59. if err != nil {
  60. return time.Time{}, nil
  61. }
  62. return tr.now.Add(diff), nil
  63. }
  64. if res, ok := TryParseUnixMsEpoch(tr.To); ok {
  65. return res, nil
  66. }
  67. return time.Time{}, fmt.Errorf("cannot parse to value %s", tr.To)
  68. }
  69. func (tr *TimeRange) MustGetFrom() time.Time {
  70. res, err := tr.ParseFrom()
  71. if err != nil {
  72. return time.Unix(0, 0)
  73. }
  74. return res
  75. }
  76. func (tr *TimeRange) MustGetTo() time.Time {
  77. res, err := tr.ParseTo()
  78. if err != nil {
  79. return time.Unix(0, 0)
  80. }
  81. return res
  82. }
  83. func (tr *TimeRange) GetFromAsMsEpoch() int64 {
  84. return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
  85. }
  86. func (tr *TimeRange) GetFromAsSecondsEpoch() int64 {
  87. return tr.GetFromAsMsEpoch() / 1000
  88. }
  89. func (tr *TimeRange) GetFromAsTimeUTC() time.Time {
  90. return tr.MustGetFrom().UTC()
  91. }
  92. func (tr *TimeRange) GetToAsMsEpoch() int64 {
  93. return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
  94. }
  95. func (tr *TimeRange) GetToAsSecondsEpoch() int64 {
  96. return tr.GetToAsMsEpoch() / 1000
  97. }
  98. func (tr *TimeRange) GetToAsTimeUTC() time.Time {
  99. return tr.MustGetTo().UTC()
  100. }
  101. // EpochPrecisionToMs converts epoch precision to millisecond, if needed.
  102. // Only seconds to milliseconds supported right now
  103. func EpochPrecisionToMs(value float64) float64 {
  104. s := strconv.FormatFloat(value, 'e', -1, 64)
  105. if strings.HasSuffix(s, "e+09") {
  106. return value * float64(1e3)
  107. }
  108. if strings.HasSuffix(s, "e+18") {
  109. return value / float64(time.Millisecond)
  110. }
  111. return value
  112. }