2
0

time.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package util
  2. import (
  3. "fmt"
  4. "strconv"
  5. "time"
  6. )
  7. const (
  8. // MinsPerHour expresses the amount of minutes in an hour
  9. MinsPerHour = 60.0
  10. // HoursPerDay expresses the amount of hours in a day
  11. HoursPerDay = 24.0
  12. // HoursPerMonth expresses the amount of hours in a month
  13. HoursPerMonth = 730.0
  14. // DaysPerMonth expresses the amount of days in a month
  15. DaysPerMonth = 30.42
  16. )
  17. // ParseDuration converts a Prometheus-style duration string into a Duration
  18. func ParseDuration(duration string) (*time.Duration, error) {
  19. unitStr := duration[len(duration)-1:]
  20. var unit time.Duration
  21. switch unitStr {
  22. case "s":
  23. unit = time.Second
  24. case "m":
  25. unit = time.Minute
  26. case "h":
  27. unit = time.Hour
  28. case "d":
  29. unit = 24.0 * time.Hour
  30. default:
  31. return nil, fmt.Errorf("error parsing duration: %s did not match expected format [0-9+](s|m|d|h)", duration)
  32. }
  33. amountStr := duration[:len(duration)-1]
  34. amount, err := strconv.ParseInt(amountStr, 10, 64)
  35. if err != nil {
  36. return nil, fmt.Errorf("error parsing duration: %s did not match expected format [0-9+](s|m|d|h)", duration)
  37. }
  38. dur := time.Duration(amount) * unit
  39. return &dur, nil
  40. }
  41. // ParseTimeRange returns a start and end time, respectively, which are converted from
  42. // a duration and offset, defined as strings with Prometheus-style syntax.
  43. func ParseTimeRange(duration, offset string) (*time.Time, *time.Time, error) {
  44. // endTime defaults to the current time, unless an offset is explicity declared,
  45. // in which case it shifts endTime back by given duration
  46. endTime := time.Now()
  47. if offset != "" {
  48. o, err := ParseDuration(offset)
  49. if err != nil {
  50. return nil, nil, fmt.Errorf("error parsing offset (%s): %s", offset, err)
  51. }
  52. endTime = endTime.Add(-1 * *o)
  53. }
  54. // if duration is defined in terms of days, convert to hours
  55. // e.g. convert "2d" to "48h"
  56. durationNorm, err := normalizeTimeParam(duration)
  57. if err != nil {
  58. return nil, nil, fmt.Errorf("error parsing duration (%s): %s", duration, err)
  59. }
  60. // convert time duration into start and end times, formatted
  61. // as ISO datetime strings
  62. dur, err := time.ParseDuration(durationNorm)
  63. if err != nil {
  64. return nil, nil, fmt.Errorf("errorf parsing duration (%s): %s", durationNorm, err)
  65. }
  66. startTime := endTime.Add(-1 * dur)
  67. return &startTime, &endTime, nil
  68. }
  69. func normalizeTimeParam(param string) (string, error) {
  70. // convert days to hours
  71. if param[len(param)-1:] == "d" {
  72. count := param[:len(param)-1]
  73. val, err := strconv.ParseInt(count, 10, 64)
  74. if err != nil {
  75. return "", err
  76. }
  77. val = val * 24
  78. param = fmt.Sprintf("%dh", val)
  79. }
  80. return param, nil
  81. }