package calendar import ( "context" "sort" "time" ) // Interval ist ein "beschäftigt"-Zeitraum. Enthält bewusst KEINE Termindetails, // nur Start und Ende – mehr verlässt den Kalender des Nutzers nie. type Interval struct { Start time.Time End time.Time } type Provider interface { // FetchBusy liefert alle busy-Zeiträume im Fenster [from, to). FetchBusy(ctx context.Context, from, to time.Time) ([]Interval, error) } // clampIntervals schneidet Intervalle aufs Fenster zurecht, verwirft ungültige // und sortiert das Ergebnis. func clampIntervals(in []Interval, from, to time.Time) []Interval { out := make([]Interval, 0, len(in)) for _, iv := range in { if !iv.End.After(iv.Start) { continue } if iv.Start.Before(from) { iv.Start = from } if iv.End.After(to) { iv.End = to } if iv.End.After(iv.Start) { out = append(out, iv) } } sort.Slice(out, func(i, j int) bool { return out[i].Start.Before(out[j].Start) }) return out }