scheduling

package
v0.4.8 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package scheduling provides time and scheduling primitives for booking systems. It includes types for representing time-of-day, weekdays, opening hours, time slots, and orphan gap detection.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCloseBeforeOpen is returned when close time is not after open time.
	ErrCloseBeforeOpen = errors.New("close time must be after open time")
)

Errors for opening hours validation.

View Source
var ErrEndBeforeStart = errors.New("end time must be after start time")

Functions

This section is empty.

Types

type DayHours

type DayHours struct {
	// CloseTime is when the facility closes.
	CloseTime TimeOfDay `json:"close_time"`
	// IsClosed indicates if the facility is closed this day.
	IsClosed bool `json:"is_closed"`
	// OpenTime is when the facility opens.
	OpenTime TimeOfDay `json:"open_time"`
	// Weekday is the day of the week.
	Weekday Weekday `json:"weekday"`
}

DayHours represents the opening hours for a single day.

func NewClosedDay

func NewClosedDay(weekday Weekday) *DayHours

NewClosedDay creates a closed day for a specific weekday.

func NewDayHours

func NewDayHours(weekday Weekday, openTime, closeTime TimeOfDay) (*DayHours, error)

NewDayHours creates opening hours for a specific day. Returns error if close time is not after open time.

func (*DayHours) Duration

func (a *DayHours) Duration() int

Duration returns the number of minutes the facility is open.

func (*DayHours) IsOpen

func (a *DayHours) IsOpen(t TimeOfDay) bool

IsOpen returns true if the facility is open at the given time.

func (*DayHours) SlotCount

func (a *DayHours) SlotCount(slotDurationMinutes int) int

SlotCount returns the number of slots available given slot duration.

func (*DayHours) Validate

func (a *DayHours) Validate() error

Validate checks if the day hours are valid.

type DaySlots

type DaySlots struct {
	Date  time.Time `json:"date"`
	Slots []*Slot   `json:"slots"`
}

DaySlots represents all slots for a single day.

func NewDaySlots

func NewDaySlots(date time.Time, dayHours *DayHours, slotDurationMinutes int) *DaySlots

NewDaySlots creates slots for a day based on opening hours and slot duration.

func (*DaySlots) AvailableCount

func (a *DaySlots) AvailableCount() int

AvailableCount returns the number of available slots.

func (*DaySlots) GetSlot

func (a *DaySlots) GetSlot(id string) *Slot

GetSlot returns the slot by ID.

func (*DaySlots) MarkBooked

func (a *DaySlots) MarkBooked(slotID string) bool

MarkBooked marks a slot as booked.

func (*DaySlots) MarkHeld

func (a *DaySlots) MarkHeld(slotID string) bool

MarkHeld marks a slot as held.

type OpeningHours

type OpeningHours struct {
	// Days maps weekday to opening hours.
	Days map[Weekday]*DayHours `json:"days"`
}

OpeningHours represents the weekly opening hours for a facility.

func NewOpeningHours

func NewOpeningHours() *OpeningHours

NewOpeningHours creates a new opening hours schedule. All days default to closed.

func (*OpeningHours) GetDayHours

func (a *OpeningHours) GetDayHours(weekday Weekday) *DayHours

GetDayHours returns the opening hours for a specific weekday.

func (*OpeningHours) GetDayHoursForDate

func (a *OpeningHours) GetDayHoursForDate(date time.Time) *DayHours

GetDayHoursForDate returns the opening hours for a specific date.

func (*OpeningHours) IsOpenOn

func (a *OpeningHours) IsOpenOn(weekday Weekday) bool

IsOpenOn returns true if the facility is open on the given weekday.

func (*OpeningHours) SetClosed

func (a *OpeningHours) SetClosed(weekday Weekday)

SetClosed sets the facility as closed for a specific day.

func (*OpeningHours) SetDayHours

func (a *OpeningHours) SetDayHours(hours *DayHours) error

SetDayHours sets the opening hours for a specific day.

func (*OpeningHours) SetOpen

func (a *OpeningHours) SetOpen(weekday Weekday, openTime, closeTime TimeOfDay) error

SetOpen sets the facility as open for a specific day.

func (*OpeningHours) Validate

func (a *OpeningHours) Validate() error

Validate checks if all opening hours are valid.

type OrphanGap

type OrphanGap struct {
	// EndTime is the end time of the gap.
	EndTime TimeOfDay `json:"end_time"`
	// Reason is the i18n key explaining why this gap is an orphan.
	Reason OrphanGapReason `json:"reason"`
	// StartTime is the start time of the gap.
	StartTime TimeOfDay `json:"start_time"`
}

OrphanGap represents an unusable 30-minute gap created by a selection.

type OrphanGapDetector

type OrphanGapDetector struct {
	// contains filtered or unexported fields
}

OrphanGapDetector detects orphan gaps created by a selection.

func NewOrphanGapDetector

func NewOrphanGapDetector(dayHours *DayHours, existingBookings []*TimeRange, slotDuration int) *OrphanGapDetector

NewOrphanGapDetector creates a new orphan gap detector.

func (*OrphanGapDetector) Detect

func (a *OrphanGapDetector) Detect(selection *TimeRange) []*OrphanGap

Detect finds all orphan gaps that would be created by the given selection. An orphan gap is a 30-minute slot that becomes unbookable because: 1. It's between the selection and the start of the booking window 2. It's between the selection and the end of the booking window 3. It's between the selection and an existing booking

Returns nil if no orphan gaps are detected.

func (*OrphanGapDetector) GetFirstOrphanGap

func (a *OrphanGapDetector) GetFirstOrphanGap(selection *TimeRange) *OrphanGap

GetFirstOrphanGap returns the first detected orphan gap, or nil if none.

func (*OrphanGapDetector) HasOrphanGaps

func (a *OrphanGapDetector) HasOrphanGaps(selection *TimeRange) bool

HasOrphanGaps returns true if the selection would create any orphan gaps.

type OrphanGapReason

type OrphanGapReason string

OrphanGapReason represents the reason for an orphan gap.

const (
	OrphanGapReasonBetweenBookings OrphanGapReason = "reason.orphan_gap.between_bookings"
	OrphanGapReasonEndOfWindow     OrphanGapReason = "reason.orphan_gap.end_of_window"
	OrphanGapReasonStartOfWindow   OrphanGapReason = "reason.orphan_gap.start_of_window"
)

Orphan gap reason keys (i18n keys).

type Slot

type Slot struct {
	Date      time.Time `json:"date"`
	EndTime   TimeOfDay `json:"end_time"`
	ID        string    `json:"id"`
	StartTime TimeOfDay `json:"start_time"`
	State     SlotState `json:"state"`
}

Slot represents a single bookable time slot.

func NewSlot

func NewSlot(date time.Time, startTime, endTime TimeOfDay, state SlotState) *Slot

NewSlot creates a new slot.

func (*Slot) Duration

func (a *Slot) Duration() int

Duration returns the slot duration in minutes.

func (*Slot) IsAvailable

func (a *Slot) IsAvailable() bool

IsAvailable returns true if the slot can be booked.

type SlotState

type SlotState string

SlotState represents the availability state of a time slot.

const (
	SlotStateAvailable   SlotState = "available"
	SlotStateBooked      SlotState = "booked"
	SlotStateHeld        SlotState = "held"
	SlotStateMaintenance SlotState = "maintenance"
)

Slot states.

type TimeOfDay

type TimeOfDay int

TimeOfDay represents a time without date (hours and minutes). Minutes are stored as offset from midnight (0-1439).

func MustTimeOfDay

func MustTimeOfDay(hours, minutes int) TimeOfDay

MustTimeOfDay creates a TimeOfDay from hours and minutes, panics on error.

func NewTimeOfDay

func NewTimeOfDay(hours, minutes int) (TimeOfDay, error)

NewTimeOfDay creates a TimeOfDay from hours and minutes. Returns error if hours or minutes are out of range.

func ParseTimeOfDay

func ParseTimeOfDay(value string) (TimeOfDay, error)

ParseTimeOfDay parses a time-of-day string in "HH:MM" format.

func (TimeOfDay) Add

func (a TimeOfDay) Add(minutes int) TimeOfDay

Add adds minutes to the time and returns a new TimeOfDay. Does not wrap around midnight.

func (TimeOfDay) After

func (a TimeOfDay) After(other TimeOfDay) bool

After returns true if this time is after other.

func (TimeOfDay) Before

func (a TimeOfDay) Before(other TimeOfDay) bool

Before returns true if this time is before other.

func (TimeOfDay) Equal

func (a TimeOfDay) Equal(other TimeOfDay) bool

Equal returns true if this time equals other.

func (TimeOfDay) Hours

func (a TimeOfDay) Hours() int

Hours returns the hour component (0-23).

func (TimeOfDay) Minutes

func (a TimeOfDay) Minutes() int

Minutes returns the minute component (0-59).

func (TimeOfDay) String

func (a TimeOfDay) String() string

String returns the time in HH:MM format.

func (TimeOfDay) TotalMinutes

func (a TimeOfDay) TotalMinutes() int

TotalMinutes returns the total minutes from midnight.

type TimeRange

type TimeRange struct {
	// contains filtered or unexported fields
}

TimeRange represents a contiguous time range for a selection. This is a value object - immutable once created.

func NewTimeRange

func NewTimeRange(date time.Time, startTime, endTime TimeOfDay) (*TimeRange, error)

NewTimeRange creates a new time range. Returns an error if end time is not after start time.

func (*TimeRange) Contains

func (a *TimeRange) Contains(t TimeOfDay) bool

Contains returns true if the given time is within the range.

func (*TimeRange) Date

func (a *TimeRange) Date() time.Time

Date returns the date of the time range.

func (*TimeRange) Duration

func (a *TimeRange) Duration() int

Duration returns the duration in minutes.

func (*TimeRange) EndTime

func (a *TimeRange) EndTime() TimeOfDay

EndTime returns the end time of the range.

func (*TimeRange) Overlaps

func (a *TimeRange) Overlaps(other *TimeRange) bool

Overlaps returns true if this range overlaps with another.

func (*TimeRange) SlotCount

func (a *TimeRange) SlotCount(slotDurationMinutes int) int

SlotCount returns the number of slots in this range.

func (*TimeRange) StartTime

func (a *TimeRange) StartTime() TimeOfDay

StartTime returns the start time of the range.

func (*TimeRange) String

func (a *TimeRange) String() string

String returns a human-readable representation of the time range.

type Weekday

type Weekday int

Weekday represents a day of the week for opening hours.

const (
	Monday Weekday = iota
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
	Sunday
)

Weekday constants for opening hours.

func WeekdayFromGoWeekday

func WeekdayFromGoWeekday(w time.Weekday) Weekday

WeekdayFromGoWeekday converts time.Weekday to facility Weekday.

func (Weekday) GoWeekday

func (a Weekday) GoWeekday() time.Weekday

GoWeekday converts facility Weekday to time.Weekday.

func (Weekday) String

func (a Weekday) String() string

String returns the string representation of a weekday.

Jump to

Keyboard shortcuts

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