package quota import ( _ "time/tzdata" // embedded zone database: TZ-aware windows work in scratch containers "time" "ukrrs.com/mopac/harness/internal/config" ) // Schedule is the TZ-aware peak window. z.ai peak hours are documented as // Monday-Friday 14:00-18:00 Singapore (UTC+8), which is 01:00-05:00 // America/Chicago in winter (CST) / 00:00-04:00 during US DST — the default // matches Charles's "0100 to 0500 CST" and is configurable to the minute. // The window may wrap midnight (start > end): then it covers evenings of // the start day plus early mornings of the following day. type Schedule struct { Start, End time.Duration // minutes-since-midnight in Loc Loc *time.Location WeekdaysOnly bool } // NewSchedule parses the window out of the [quota] config fields. func NewSchedule(peakStart, peakEnd, tzName string, weekdaysOnly bool) (Schedule, error) { start, err := config.ParseHHMM(peakStart) if err != nil { return Schedule{}, err } end, err := config.ParseHHMM(peakEnd) if err != nil { return Schedule{}, err } loc, err := time.LoadLocation(tzName) if err != nil { return Schedule{}, err } return Schedule{Start: start, End: end, Loc: loc, WeekdaysOnly: weekdaysOnly}, nil } // SameDay reports whether t is inside the window without crossing midnight // (start <= t < end, single-day window). func (s Schedule) inWindow(mins time.Duration) bool { if s.Start <= s.End { return mins >= s.Start && mins < s.End } // Wrapped window: [start, 24h) of the start day, [0, end) of the next. return mins >= s.Start || mins < s.End } // InPeak reports whether t falls inside the peak window, evaluated in the // schedule's timezone. For wrapped windows the weekday check applies to the // day the window STARTED on (a Sunday 22:00-02:00 window is off all week // when weekdays-only, because it starts on Sunday). func (s Schedule) InPeak(t time.Time) bool { local := t.In(s.Loc) mins := time.Duration(local.Hour())*time.Hour + time.Duration(local.Minute())*time.Minute if s.Start <= s.End { if !s.inWindow(mins) { return false } return !s.WeekdaysOnly || isWeekday(local) } // Evening half: today carries the window. if mins >= s.Start { return !s.WeekdaysOnly || isWeekday(local) } // Morning half: the window started yesterday. if mins < s.End { return !s.WeekdaysOnly || isWeekday(local.AddDate(0, 0, -1)) } return false } func isWeekday(t time.Time) bool { wd := t.Weekday() return wd >= time.Monday && wd <= time.Friday }