You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
2.3 KiB

  1. package models
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "strconv"
  7. "strings"
  8. "time"
  9. )
  10. type TimeOfDay int
  11. func (t *TimeOfDay) UnmarshalJSON(v []byte) error {
  12. if bytes.Equal(v, []byte("null")) {
  13. *t = -1
  14. }
  15. var str string
  16. err := json.Unmarshal(v, &str)
  17. if err != nil {
  18. var n int
  19. err = json.Unmarshal(v, &n)
  20. if err != nil {
  21. return err
  22. }
  23. if n < -1 && n >= 86400 {
  24. return fmt.Errorf("value outside range 0..86400: %d", n)
  25. }
  26. }
  27. t2, err := ParseTimeOfDay(str)
  28. if err != nil {
  29. return err
  30. }
  31. *t = t2
  32. return nil
  33. }
  34. func (t TimeOfDay) MarshalJSON() ([]byte, error) {
  35. if t.IsNever() {
  36. return []byte("null"), nil
  37. }
  38. return json.Marshal(t.String())
  39. }
  40. const Never = TimeOfDay(-1)
  41. func (t *TimeOfDay) String() string {
  42. if *t < 0 {
  43. return "n/a"
  44. }
  45. return fmt.Sprintf("%02d:%02d:%02d", *t/3600, (*t/60)%60, *t%60)
  46. }
  47. func (t *TimeOfDay) StringPtr() *string {
  48. if *t < 0 {
  49. return nil
  50. }
  51. s := t.String()
  52. return &s
  53. }
  54. func (t TimeOfDay) IsNever() bool {
  55. return t == Never
  56. }
  57. func (t TimeOfDay) IsBetween(from TimeOfDay, to TimeOfDay) bool {
  58. if from == to {
  59. return t == from
  60. } else if from > to {
  61. return t >= from || t <= to
  62. } else {
  63. return t >= from && t <= to
  64. }
  65. }
  66. func CurrentTimeOfDay() TimeOfDay {
  67. return TimeOfDayFromDate(time.Now().Local())
  68. }
  69. func TimeOfDayFromDate(date time.Time) TimeOfDay {
  70. return NewTimeOfDay(date.Hour(), date.Minute(), date.Second())
  71. }
  72. func NewTimeOfDay(hours, minutes, seconds int) TimeOfDay {
  73. return TimeOfDay(((hours % 24) * 3600) + ((minutes % 60) * 60) + seconds)
  74. }
  75. func ParseTimeOfDayPtr(str *string) (TimeOfDay, error) {
  76. if str == nil {
  77. return Never, nil
  78. }
  79. return ParseTimeOfDay(*str)
  80. }
  81. func ParseTimeOfDay(str string) (TimeOfDay, error) {
  82. if str == "" || str == "n/a" || str == "N/A" {
  83. return -1, nil
  84. }
  85. split := strings.SplitN(str, ":", 4)
  86. res := 0
  87. n, err := strconv.Atoi(split[0])
  88. if err != nil {
  89. return Never, err
  90. }
  91. res += n * 3600
  92. if len(split) >= 2 {
  93. n, err := strconv.Atoi(split[1])
  94. if err != nil {
  95. return Never, err
  96. }
  97. res += n * 60
  98. }
  99. if len(split) >= 3 {
  100. n, err := strconv.Atoi(split[2])
  101. if err != nil {
  102. return Never, err
  103. }
  104. res += n
  105. }
  106. if res >= 86400 || res < 0 {
  107. return Never, fmt.Errorf("invalid time of day string %s (=%d)", str, res)
  108. }
  109. return TimeOfDay(res), nil
  110. }