schedule

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultDayPartition = DayPartition{
	{Name: "night", Span: DaySlot{Start: TimeOfDay{Hour: 22}, End: TimeOfDay{Hour: 29}}},
	{Name: "morning", Span: DaySlot{Start: TimeOfDay{Hour: 5}, End: TimeOfDay{Hour: 12}}},
	{Name: "lunchtime", Span: DaySlot{Start: TimeOfDay{Hour: 12}, End: TimeOfDay{Hour: 14}}},
	{Name: "afternoon", Span: DaySlot{Start: TimeOfDay{Hour: 14}, End: TimeOfDay{Hour: 17}}},
	{Name: "evening", Span: DaySlot{Start: TimeOfDay{Hour: 17}, End: TimeOfDay{Hour: 22}}},
}

DefaultDayPartition is the canonical partition of the day. Replace it (or build a custom Vocabulary) for app-specific slicing — Validate any custom partition first.

View Source
var DefaultWorkingHoursSchedule = Schedule{
	Days:      []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday, time.Friday},
	StartHour: 9,
	EndHour:   17,
}

DefaultWorkingHoursSchedule is a standard Monday-Friday 9-17 working hours schedule.

Functions

This section is empty.

Types

type CompositeSchedule added in v0.0.9

type CompositeSchedule struct {
	Groups   []DaySchedule
	Location *time.Location
}

CompositeSchedule combines multiple DaySchedule groups into one. A day matches if any group matches; slots are the union of all matching groups.

func (CompositeSchedule) MatchesDay added in v0.0.9

func (cs CompositeSchedule) MatchesDay(t time.Time) bool

func (CompositeSchedule) PrevMatchingDay added in v0.0.9

func (cs CompositeSchedule) PrevMatchingDay(from time.Time) time.Time

func (CompositeSchedule) SlotsForDay added in v0.0.9

func (cs CompositeSchedule) SlotsForDay(day time.Time) []TimeSlot

type DayPart added in v0.3.0

type DayPart struct {
	Name string  // canonical singular: "morning", "night", ...
	Span DaySlot // may cross midnight (End.Hour >= 24)
}

DayPart is one named slice of the day within a DayPartition.

type DayPartition added in v0.3.0

type DayPartition []DayPart

DayPartition is an ordered set of DayParts that must cover the full 24h exactly once (no gaps, no overlaps, modulo midnight wrap) — one source of truth for both filtering ("mornings") and classification (PartOf). The invariant is enforced by Validate, which makes PartOf a total function and therefore a safe group-by key.

func (DayPartition) PartOf added in v0.3.0

func (dp DayPartition) PartOf(t time.Time) DayPart

PartOf classifies t's wall clock into its part of the day. On a Validate'd partition it is total: every minute belongs to exactly one part. A partition violating the invariant may return the zero DayPart for uncovered minutes.

func (DayPartition) Validate added in v0.3.0

func (dp DayPartition) Validate() error

Validate enforces the partition invariant: every minute of the day is covered by exactly one part. Overlaps and gaps are reported with the exact wall-clock minute so a misconfigured custom partition fails loudly instead of silently misclassifying.

type DaySchedule added in v0.0.9

type DaySchedule interface {
	MatchesDay(t time.Time) bool
	SlotsForDay(day time.Time) []TimeSlot
	PrevMatchingDay(from time.Time) time.Time
}

DaySchedule is the common interface for schedule types that can produce per-day time slots and navigate matching days.

type DaySlot added in v0.0.9

type DaySlot struct {
	Start TimeOfDay
	End   TimeOfDay
}

DaySlot represents a continuous time window within a day, possibly crossing midnight.

type MultiSlotSchedule added in v0.0.9

type MultiSlotSchedule struct {
	Days     []time.Weekday
	DaySlots []DaySlot
	Location *time.Location
}

MultiSlotSchedule defines multiple disjoint time windows per day.

func (MultiSlotSchedule) MatchesDay added in v0.0.9

func (ms MultiSlotSchedule) MatchesDay(t time.Time) bool

MatchesDay returns true if t's weekday is one of the schedule's days.

func (MultiSlotSchedule) PrevMatchingDay added in v0.0.9

func (ms MultiSlotSchedule) PrevMatchingDay(from time.Time) time.Time

PrevMatchingDay finds the previous day matching the schedule.

func (MultiSlotSchedule) SlotsForDay added in v0.0.9

func (ms MultiSlotSchedule) SlotsForDay(day time.Time) []TimeSlot

SlotsForDay generates time slots for a single day from multi-slot config. Cross-midnight slots (hour >= 24) naturally extend into the next calendar day.

type Schedule

type Schedule struct {
	Days      []time.Weekday // e.g., [Mon, Tue, Wed, Thu, Fri]
	StartHour int            // e.g., 9
	EndHour   int            // e.g., 17
	Gaps      []TimeRange    // optional gaps (e.g., lunch: [{12, 13}])
	Location  *time.Location // timezone
}

Schedule defines working hours for a set of days.

func (Schedule) AvailableMinutes

func (s Schedule) AvailableMinutes(day time.Time) int

AvailableMinutes returns total available minutes in schedule for a day.

func (Schedule) Contains

func (s Schedule) Contains(t time.Time) bool

Contains returns true if t matches both the day and time of the schedule.

func (Schedule) MatchesDay

func (s Schedule) MatchesDay(t time.Time) bool

MatchesDay returns true if t's weekday is one of the schedule's days.

func (Schedule) MatchesTime

func (s Schedule) MatchesTime(t time.Time) bool

MatchesTime returns true if t's time-of-day is within schedule hours (excluding gaps).

func (Schedule) NextMatchingDay

func (s Schedule) NextMatchingDay(from time.Time) time.Time

NextMatchingDay finds the next day matching the schedule.

func (Schedule) NextNonMatchingDay

func (s Schedule) NextNonMatchingDay(from time.Time) time.Time

NextNonMatchingDay finds the next day not matching the schedule.

func (Schedule) PrevMatchingDay

func (s Schedule) PrevMatchingDay(from time.Time) time.Time

PrevMatchingDay finds the previous day matching the schedule. e.g., called on Sunday -> returns Friday (for Mon-Fri schedule).

func (Schedule) PrevNonMatchingDay

func (s Schedule) PrevNonMatchingDay(from time.Time) time.Time

PrevNonMatchingDay finds the previous day not matching the schedule. e.g., called on Monday -> returns Sunday (for Mon-Fri schedule).

func (Schedule) SlotsForDay

func (s Schedule) SlotsForDay(day time.Time) []TimeSlot

SlotsForDay generates hour slots for a single day If gaps are configured, returns multiple slots (split by gaps).

func (Schedule) SlotsForRange

func (s Schedule) SlotsForRange(from, to time.Time) []TimeSlot

SlotsForRange generates slots across multiple days.

type TimeOfDay added in v0.0.9

type TimeOfDay struct {
	Hour   int // 0-35
	Minute int // 0-59
}

TimeOfDay represents a time-of-day with minute precision. Hour can be >= 24 for cross-midnight support (e.g., 26:00 = 2AM next day).

func (TimeOfDay) ToDuration added in v0.0.9

func (t TimeOfDay) ToDuration() time.Duration

ToDuration converts TimeOfDay to a duration from midnight.

type TimeRange

type TimeRange struct {
	StartHour int // e.g., 12
	EndHour   int // e.g., 13
}

TimeRange represents a time range within a day (hour-based).

type TimeSlot

type TimeSlot struct {
	Start time.Time
	End   time.Time
}

TimeSlot represents a continuous time range.

func (TimeSlot) Duration

func (ts TimeSlot) Duration() time.Duration

Duration returns the duration of the slot.

type Vocabulary added in v0.3.0

type Vocabulary struct {
	Partition DayPartition
	Extra     map[string]WeekPatterns // app-specific terms, e.g. "officehours"
}

Vocabulary resolves human terms ("weekends", "mornings") to week patterns. The zero-config default (package-level ParsePatterns) uses DefaultDayPartition and the built-in weekday terms; apps may build their own to add domain words or a custom partition.

This is deliberately distinct from the alias system of the root package: aliases resolve to absolute instants/periods ("last-week" → a concrete Monday); a week pattern is a recurring predicate with no anchor in absolute time.

func DefaultVocabulary added in v0.3.0

func DefaultVocabulary() Vocabulary

DefaultVocabulary is the built-in vocabulary: weekday terms plus DefaultDayPartition part names.

func (Vocabulary) ParsePatterns added in v0.3.0

func (v Vocabulary) ParsePatterns(s string) (WeekPatterns, error)

ParsePatterns converts a comma-separated list of vocabulary terms into a union of week patterns:

input  := term ("," term)*      // comma = union (OR)
term   := dayset | daypart
dayset := "monday(s)" … "sunday(s)" | "weekend(s)"
        | "workingday(s)" | "workday(s)" | "weekday(s)"
daypart:= partition part name, singular or plural

Terms are case-insensitive, whitespace-trimmed and plural-tolerant. The result is a list because mixed unions ("sundays,mornings" = sundays all day OR mornings every day) are not expressible in a single {Days, Spans} conjunction. An unknown term errors listing the known vocabulary.

type WeekPattern added in v0.3.0

type WeekPattern struct {
	Days  []time.Weekday
	Spans []DaySlot
}

WeekPattern is a recurring weekly wall-clock pattern: a conjunction of "weekday ∈ Days" and "time-of-day ∈ one of Spans".

  • Days empty => every day
  • Spans empty => the whole day

Spans reuse DaySlot; End.Hour may exceed 24 (cross-midnight). A cross-midnight span is attributed to the day it starts on: {Days: [Sunday], Spans: [{22:00, 29:00}]} covers Sunday 22:00 through Monday 05:00.

Unlike Schedule, a WeekPattern has no anchor in absolute time and no timezone opinion: Contains reads the wall clock of the given time value in its own location. Callers own locality.

func (WeekPattern) Contains added in v0.3.0

func (p WeekPattern) Contains(t time.Time) bool

Contains reports whether t's wall clock matches the pattern.

The attribution rule: Contains(t) is true iff there exists a day d (t's own date or the previous date) such that weekday(d) ∈ Days (or Days is empty) and t ∈ [d+span.Start, d+span.End) for some span. A cross-midnight span belongs to the day it starts on, so a "Sunday nights" pattern includes Monday 01:00, matching human usage.

func (WeekPattern) MultiSlotSchedule added in v0.3.0

func (p WeekPattern) MultiSlotSchedule(loc *time.Location) MultiSlotSchedule

MultiSlotSchedule converts the pattern into an equivalent MultiSlotSchedule pinned to the given location, so the existing slot math (SlotsForDay, PrevMatchingDay, ...) works on patterns. Empty Days/Spans are expanded into their explicit meanings (every day / the whole day).

func (WeekPattern) Validate added in v0.3.0

func (p WeekPattern) Validate() error

Validate checks the pattern for sane weekdays and spans: minutes within 0-59, spans starting within their own day (< 24h), ending after they start and before the second midnight (< 48h).

type WeekPatterns added in v0.3.0

type WeekPatterns []WeekPattern

WeekPatterns is a union (OR) of patterns.

func ParsePatterns added in v0.3.0

func ParsePatterns(s string) (WeekPatterns, error)

ParsePatterns parses s using DefaultVocabulary.

func (WeekPatterns) Contains added in v0.3.0

func (ps WeekPatterns) Contains(t time.Time) bool

Contains reports whether t matches any of the patterns (union semantics).

func (WeekPatterns) Validate added in v0.3.0

func (ps WeekPatterns) Validate() error

Validate checks every pattern of the union.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL