-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
season.go
123 lines (103 loc) · 2.61 KB
/
season.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package jsonx
import (
"fmt"
"strconv"
"strings"
"time"
)
// GetSeasonByDate returns the season based on the given date.
func GetSeasonByDate(date SimpleDate) Season {
month := date.ToTime().Month()
switch month {
case time.December, time.January, time.February:
return Winter
case time.March, time.April, time.May:
return Spring
case time.June, time.July, time.August:
return Summer
case time.September, time.October, time.November:
return Autumn
default:
return 0 // Should never happen.
}
}
// Season is a bitmask of seasons
// Winter, Spring, Summer, Autumn.
// It is used to represent the seasons of a year.
// It is a bitmask so that multiple seasons can be set at once.
// It has methods to check if a season is set, add a season,
// remove a season, and get a string representation of the seasons.
type Season int
const (
// December, January, February.
Winter Season = 1 << iota // 1 << 0 = 1
// March, April, May.
Spring // 1 << 1 = 2
// June, July, August.
Summer // 1 << 2 = 4
// September, October, November.
Autumn // 1 << 3 = 8
// AllSeasons is a bitmask of all seasons.
// It's the number 15 because it's the sum of all seasons.
AllSeasons = Winter | Spring | Summer | Autumn // 1 + 2 + 4 + 8 = 15
)
// IsValid checks if the season is valid.
func (s Season) IsValid() bool {
return s&AllSeasons == s
}
// Is checks if the season is set in the bitmask.
func (s Season) Is(season Season) bool {
return s&season != 0
}
// Add adds a season to the bitmask.
func (s *Season) Add(season Season) {
*s |= season
}
// Remove removes a season from the bitmask.
func (s *Season) Remove(season Season) {
*s &= ^season
}
// String returns the string representation of the season(s).
func (s Season) String() string {
var seasons []string
if s.Is(Winter) {
seasons = append(seasons, "Winter")
}
if s.Is(Spring) {
seasons = append(seasons, "Spring")
}
if s.Is(Summer) {
seasons = append(seasons, "Summer")
}
if s.Is(Autumn) {
seasons = append(seasons, "Autumn")
}
if len(seasons) == 0 {
return "None"
}
return strings.Join(seasons, ", ")
}
// MarshalJSON marshals the season to JSON.
// It marshals the season as a string.
func (s *Season) UnmarshalJSON(data []byte) error {
if isNull(data) {
return nil
}
data = trimQuotes(data)
if len(data) == 0 {
return nil
}
str := string(data)
constantAsInt, err := strconv.Atoi(str)
if err != nil {
return err
}
if constantAsInt == 0 { // if 0 is passed, it means All seasons.
constantAsInt = int(AllSeasons)
}
*s = Season(constantAsInt)
if !s.IsValid() {
return fmt.Errorf("%w: season: %s", ErrInvalid, str)
}
return nil
}