mirror of
https://github.com/kubereboot/kured.git
synced 2026-05-21 15:53:14 +00:00
* Add e2e test concurrency w/ signal This will help make sure the big refactoring does not break the main features. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Add podblocker test Extends test coverage to ensure nothing breaks Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Rename "version" with "variant" in tests For tests not running in different kubernetes versions, but have different tests subcases/variants, rephrase the wording "versions" as it is confusing. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Fix Staticcheck's SA1024 (subset with dupe chars) This will replace trim, taking a cutset, with Replace. This clarifies the intent to remove a substring. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Fix Staticcheck's ST1005 According to staticcheck, Error strings should not be capitalized (ST1005). This changes the cases for our errors. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Fix incorrect string prints A few strings have evolved to eventually remove all the templating part of their strings, yet kept the formatting features. This is incorrect, and will not pass staticcheck SA1006 and S1039. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> * Add staticcheck in make tests Without this, people like myself will forget to run staticcheck. This fixes it by making it part of make tests, which will run with all the fast tests in CI. Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party> --------- Signed-off-by: Jean-Philippe Evrard <open-source@a.spamming.party>
82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package timewindow
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// TimeWindow specifies a schedule of days and times.
|
|
type TimeWindow struct {
|
|
days weekdays
|
|
location *time.Location
|
|
startTime time.Time
|
|
endTime time.Time
|
|
}
|
|
|
|
// New creates a TimeWindow instance based on string inputs specifying a schedule.
|
|
func New(days []string, startTime, endTime, location string) (*TimeWindow, error) {
|
|
tw := &TimeWindow{}
|
|
|
|
var err error
|
|
if tw.days, err = parseWeekdays(days); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tw.location, err = time.LoadLocation(location); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tw.startTime, err = parseTime(startTime, tw.location); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if tw.endTime, err = parseTime(endTime, tw.location); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return tw, nil
|
|
}
|
|
|
|
// Contains determines whether the specified time is within this time window.
|
|
func (tw *TimeWindow) Contains(t time.Time) bool {
|
|
loctime := t.In(tw.location)
|
|
if !tw.days.Contains(loctime.Weekday()) {
|
|
return false
|
|
}
|
|
|
|
start := time.Date(loctime.Year(), loctime.Month(), loctime.Day(), tw.startTime.Hour(), tw.startTime.Minute(), tw.startTime.Second(), 0, tw.location)
|
|
end := time.Date(loctime.Year(), loctime.Month(), loctime.Day(), tw.endTime.Hour(), tw.endTime.Minute(), tw.endTime.Second(), 1e9-1, tw.location)
|
|
|
|
// Time Wrap validation
|
|
// First we check for start and end time, if start is after end time
|
|
// Next we need to validate if we want to wrap to the day before or to the day after
|
|
// For that we check the loctime value to see if it is before end time, we wrap with the day before
|
|
// Otherwise we wrap to the next day.
|
|
if tw.startTime.After(tw.endTime) {
|
|
if loctime.Before(end) {
|
|
start = start.Add(-24 * time.Hour)
|
|
} else {
|
|
end = end.Add(24 * time.Hour)
|
|
}
|
|
}
|
|
|
|
return (loctime.After(start) || loctime.Equal(start)) && (loctime.Before(end) || loctime.Equal(end))
|
|
}
|
|
|
|
// String returns a string representation of this time window.
|
|
func (tw *TimeWindow) String() string {
|
|
return fmt.Sprintf("%s between %02d:%02d and %02d:%02d %s", tw.days.String(), tw.startTime.Hour(), tw.startTime.Minute(), tw.endTime.Hour(), tw.endTime.Minute(), tw.location.String())
|
|
}
|
|
|
|
// parseTime tries to parse a time with several formats.
|
|
func parseTime(s string, loc *time.Location) (time.Time, error) {
|
|
fmts := []string{"15:04", "15:04:05", "03:04pm", "15", "03pm", "3pm"}
|
|
for _, f := range fmts {
|
|
if t, err := time.ParseInLocation(f, s, loc); err == nil {
|
|
return t, nil
|
|
}
|
|
}
|
|
|
|
return time.Now(), fmt.Errorf("invalid time format: %s", s)
|
|
}
|