timeinterval

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 12, 2022 License: MIT Imports: 4 Imported by: 2

README

time-interval godoc license

This package helps to work with time intervals. The functionality allows you to perform the following basic operations:

  • Union - merging of time intervals
  • Intersection - finding intersections of regular intervals
  • Except - differentiation between fixed intervals
  • Equal - comparison of time intervals
  • IsIntersection - check for intersection of time intervals

install

go get github.com/go-follow/time-interval

usage

To start using the functionality, you need to initialize a time slot or time slots. Attention: when initializing intervals, it is important to know that the end date of the interval must be greater than the start date of the interval.

An example of using a package

package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 17, 10, 0, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 17, 15, 0, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 17, 14, 0, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 17, 19, 0, 0, 0, time.UTC)
    
    newInt, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    newInt2, err := interval.New(timeStart2, timeEnd2)
    if err != nil {
        log.Fatal(err)
    }
    
    newIntMany := interval.NewMany(newInt, newInt2)
    result := newIntMany.Union()
    fmt.Println(result.String()) // 2020-10-17 10:00:00 +0000 UTC - 2020-10-17 19:00:00 +0000 UTC
}

examples

  • Except

For the Except operation, it is important where the subtraction comes from. For SpanMany, before returning the final result, is sorted and merged

package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 18, 9, 0, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 18, 12, 0, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 18, 11, 0, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 18, 15, 0, 0, 0, time.UTC)

    ti1, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    ti2, err := interval.New(timeStart2, timeEnd2)
    if err != nil {
        log.Fatal(err)
    }
    
    // ti1 \ ti2
    ti1ExceptTi2 := ti1.Except(ti2)
    fmt.Println(ti1ExceptTi2.String()) // [ 2020-10-18 10:00:00 +0000 UTC - 2020-10-18 11:00:00 +0000 UTC ]
    
    // ti2 \ ti1
    ti2ExceptTi1 := ti2.Except(ti1)
    fmt.Println(ti2ExceptTi1.String()) // [ 2020-10-18 12:00:00 +0000 UTC - 2020-10-18 15:00:00 +0000 UTC ]

    ti1, err := interval.New(time.Date(2020, 10, 18, 7, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 10, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    ti2, err := interval.New(time.Date(2020, 10, 18, 14, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 15, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    ti3, err := interval.New(interval.New(time.Date(2020, 10, 18, 12, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 16, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    ti4, err := interval.New(time.Date(2020, 10, 18, 12, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 14, 30, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    ti5, err := interval.New(time.Date(2020, 10, 18, 14, 33, 0, 0, time.UTC), time.Date(2020, 10, 18, 18, 0, 0, 0, time.UTC)),
    if err != nil {
        log.Fatal(err)
    }
    // Except for SpanMany
    intervalMany := interval.NewMany(ti1, ti2, ti3, ti4, ti5)
    intervalInput, err := interval.New(time.Date(2020, 10, 18, 14, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 15, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    exceptMany := intervalMany.Except(intervalInput)

    // [
    //    2020-10-18 07:00:00 +0000 UTC - 2020-10-18 10:00:00 +0000 UTC
    //    2020-10-18 12:00:00 +0000 UTC - 2020-10-18 14:00:00 +0000 UTC
    //    2020-10-18 15:00:00 +0000 UTC - 2020-10-18 18:00:00 +0000 UTC
    // ]

    fmt.Println(exceptMany.String())         				    			     
}
  • Union

for SpanMany union operation concatenates and sorts the original result

package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 17, 12, 0, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 17, 14, 0, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 17, 22, 0, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 17, 23, 0, 0, 0, time.UTC)
    timeStart3 := time.Date(2020, 10, 17, 13, 0, 0, 0, time.UTC)
    timeEnd3 := time.Date(2020, 10, 17, 17, 0, 0, 0, time.UTC)
    timeStart4 := time.Date(2020, 10, 17, 7, 0, 0, 0, time.UTC)
    timeEnd4 :=  time.Date(2020, 10, 17, 10, 0, 0, 0, time.UTC)
    timeStart5 := time.Date(2020, 10, 17, 21, 0, 0, 0, time.UTC)
    timeEnd5 := time.Date(2020, 10, 17, 23, 0, 0, 0, time.UTC)
    timeStart6 := time.Date(2020, 10, 17, 11, 0, 0, 0, time.UTC)
    timeEnd6 := time.Date(2020, 10, 17, 15, 0, 0, 0, time.UTC)
    
    timeSpan, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    timeInput2, err := interval.New(timeStart2, timeEnd2)
    if err != nil {
        log.Fatal(err)
    }
    timeInput3, err := interval.New(timeStart3, timeEnd3)
    if err != nil {
        log.Fatal(err)
    }
    result := timeSpan.Union(timeInput)

    // [
    //	2020-10-17 12:00:00 +0000 UTC - 2020-10-17 17:00:00 +0000 UTC
    // ]
    fmt.Println(result.String())

   

    timeSpanMany1 := interval.NewMany(
        timeSpan,
        timeInput2,
        timeInput3
    )
    timeSpanMany2 := interval.NewMany()
    if err := timeSpanMany2.Add(timeStart4, timeEnd4); err != nil {
        log.Fatal(err)
    }
    timeInput5, err := interval.New(timeStart5, timeEnd5)
    if err != nil {
        log.Fatal(err)
    }
    timeInput6, err := interval.New(timeStart6, timeEnd6)
    if err != nil {
        log.Fatal(err)
    }
    timeSpanMany2.AddMany(timeInput5, timeInput6)

    resultMany := timeSpanMany1.Union(timeSpanMany2)

    // [
    //	2020-10-17 07:00:00 +0000 UTC - 2020-10-17 10:00:00 +0000 UTC
    //	2020-10-17 11:00:00 +0000 UTC - 2020-10-17 17:00:00 +0000 UTC
    //	2020-10-17 21:00:00 +0000 UTC - 2020-10-17 23:00:00 +0000 UTC
    // ]

    fmt.Println(resultMany.String())  
        				    			     
}
  • Intersection
package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 17, 7, 0, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 17, 12, 0, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 17, 10, 0, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 17, 15, 0, 0, 0, time.UTC)
    timeStart3 := time.Date(2020, 10, 17, 20, 0, 0, 0, time.UTC)
    timeEnd3 := time.Date(2020, 10, 17, 22, 0, 0, 0, time.UTC)
    timeStart4 := time.Date(2020, 10, 17, 18, 0, 0, 0, time.UTC)
    timeEnd4 :=	time.Date(2020, 10, 17, 23, 0, 0, 0, time.UTC)
    timeStart5 := time.Date(2020, 10, 17, 7, 0, 0, 0, time.UTC)
    timeEnd5 := time.Date(2020, 10, 17, 10, 0, 0, 0, time.UTC)

    newInt, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    newInt2, err := interval.New(timeStart2, timeEnd2)
    if err != nil {
        log.Fatal(err)
    }

    result := newInt.Intersection(newInt2)
    fmt.Println(result.String()) // 2020-10-17 10:00:00 +0000 UTC - 2020-10-17 12:00:00 +0000 UTC

    timeStartInput := time.Date(2020, 10, 17, 10, 0, 0, 0, time.UTC)
    timeEndInput := time.Date(2020, 10, 17, 19, 0, 0, 0, time.UTC)
    intervalInput, err := interval.New(timeStartInput, timeEndInput)
    if err != nil {
        log.Fatal(err)
    }
    newInt3, err := interval.New(timeStart3, timeEnd3)
    if err != nil {
        log.Fatal(err)
    }
    newInt4, err := interval.New(timeStart4, timeEnd4)
    if err != nil {
        log.Fatal(err)
    }
    newInt5, err := interval.New(timeStart5, timeEnd5)
    if err != nil {
        log.Fatal(err)
    }
    timeSpanMany := interval.NewMany(newInt, newInt2, newInt3, newInt4, newInt5)
    resultMany := timeSpanMany.Intersection(intervalInput)
    // [
    //	2020-10-17 10:00:00 +0000 UTC - 2020-10-17 12:00:00 +0000 UTC
    //	2020-10-17 10:00:00 +0000 UTC - 2020-10-17 15:00:00 +0000 UTC
    //	2020-10-17 18:00:00 +0000 UTC - 2020-10-17 19:00:00 +0000 UTC
    // ]
    fmt.Println(resultMany.String())   
}
  • Equal

It is possible to pass an optional argument offset, which gives the possibility of a small error in the final result

package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 18, 15, 0, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 18, 21, 0, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 18, 14, 50, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 18, 21, 10, 0, 0, time.UTC)
    ti1, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    ti2, err := interval.New(timeStart2, timeEnd2)
    if err != nil {
        log.Fatal(err)
    }
    ti2AddSecond, err := interval.New(timeStart2, timeEnd2.Add(1 * time.Second))
    if err != nil {
        log.Fatal(err)
    }
    // Equal without offset
    fmt.Println(ti1.Equal(ti2)) // false    
    // Equal with offset 10 minute
    fmt.Println(ti1.Equal(ti2, time.Minute * 10)) // true
    // Add 1 second to ti2
    fmt.Println(ti1.Equal(ti2AddSecond, time.Minute * 10)) // false        
    
    // Equal for SpanMany
    // If there is at least one match, return true

    newInt1, err := interval.New(time.Date(2020, 10, 18, 9, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 10, 0, 0, 12, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    newInt2, err := interval.New(time.Date(2020, 10, 18, 19, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 20, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    newInt3, err := interval.New(time.Date(2020, 10, 18, 16, 55, 0, 0, time.UTC), time.Date(2020, 10, 18, 18, 0, 0, 11, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    intervalMany := interval.NewMany(newInt1, newInt2, newInt3)
    // Equal without offset
    intervalInput, err := interval.New(time.Date(2020, 10, 18, 17, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 18, 5, 0, 11, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(intervalMany.Equal(intervalInput)) // false
    // Equal with offset
    fmt.Println(intervalMany.Equal(intervalInput, time.Minute * 5)) // true
    fmt.Println(intervalMany.Equal(intervalInput, time.Minute * 4)) // false      				    			     
}
  • IsIntersection

It is possible to pass an optional argument offset, which gives the possibility of a small error in the final result

package main
 
import (
    "fmt"
    "time"

    interval "github.com/go-follow/time-interval"
)

func main() {
    timeStart1 := time.Date(2020, 10, 18, 17, 30, 0, 0, time.UTC)
    timeEnd1 := time.Date(2020, 10, 18, 18, 22, 0, 0, time.UTC)
    timeStart2 := time.Date(2020, 10, 18, 16, 0, 0, 0, time.UTC)
    timeEnd2 := time.Date(2020, 10, 18, 17, 30, 7, 0, time.UTC)
    ti1, err := interval.New(timeStart1, timeEnd1)
    if err != nil {
        log.Fatal(err)
    }
    ti2, err := interval.New(timeStart2, timeEnd2)
    if err  != nil {
        log.Fatal(err)
    }
    // IsIntersection without offset
    fmt.Println(ti1.IsIntersection(ti2)) // true
    // IsIntersection with offset 5 second
    fmt.Println(ti1.IsIntersection(ti2, time.Second * 5)) // true
    // IsIntersection with offset 10 second
    fmt.Println(ti1.IsIntersection(ti2, time.Second * 10)) // false        
    
    // IsIntersection for SpanMany
    // If there is at least one match, return true

    newInt1, err := interval.New(time.Date(2020, 10, 18, 9, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 10, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    newInt2, err := interval.New(time.Date(2020, 10, 18, 16, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 17, 5, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    newInt3, err := interval.New(time.Date(2020, 10, 18, 19, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 20, 0, 0, 0, time.UTC))
    intervalMany := interval.NewMany(newInt1, newInt2, newInt3)
    // IsIntersection without offset
    intervalInput, err := interval.New(time.Date(2020, 10, 18, 17, 0, 0, 0, time.UTC), time.Date(2020, 10, 18, 18, 0, 0, 0, time.UTC))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(intervalMany.IsIntersection(intervalInput)) // true
    // IsIntersection with offset
    fmt.Println(intervalMany.IsIntersection(intervalInput, time.Minute * 5)) // false
    fmt.Println(intervalMany.IsIntersection(intervalInput, time.Minute * 3)) // true    				    			     
}


Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SortType

type SortType int
const (
	// Ascending sort ascending (default)
	Ascending SortType = iota
	// Descending sort descending
	Descending
)

type Span

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

Span time interval

func New

func New(start, end time.Time) (Span, error)

func (*Span) End

func (s *Span) End() time.Time

End returning end time interval

func (*Span) Equal

func (s *Span) Equal(input Span, offset ...time.Duration) bool

offset - possible deviation from the time interval

func (*Span) Except

func (s *Span) Except(input Span) SpanMany

Except difference in time intervals - from input (s \ input).

func (*Span) Intersection

func (s *Span) Intersection(input Span) Span

Intersection intersection of two time intervals

func (*Span) IsContains added in v0.1.0

func (s *Span) IsContains(input Span, offset ...time.Duration) bool

IsContains check contains interval

func (*Span) IsEmpty

func (s *Span) IsEmpty() bool

IsEmpty defines empty spacing

func (*Span) IsIntersection

func (s *Span) IsIntersection(input Span, offset ...time.Duration) bool

offset - possible deviation from the time interval

func (*Span) Start

func (s *Span) Start() time.Time

Start returning start time interval

func (*Span) String added in v0.0.2

func (s *Span) String() string

String implementation interface stringer for Span

func (*Span) Union

func (s *Span) Union(input Span) SpanMany

Union union of two time intervals.

type SpanMany

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

SpanMany model containing more than one time interval.

func NewMany

func NewMany(spans ...Span) SpanMany

NewMany initialization for multiple time intervals.

func (*SpanMany) Add

func (s *SpanMany) Add(start time.Time, end time.Time) error

Add adding a time interval to SpanMany.

func (*SpanMany) AddMany

func (s *SpanMany) AddMany(spans ...Span)

AddMany adding several time slots at once to the existing one SpanMany.

func (*SpanMany) Equal

func (s *SpanMany) Equal(input Span, offset ...time.Duration) bool

offset - possible deviation from the time interval.

func (*SpanMany) Except

func (s *SpanMany) Except(input Span) SpanMany

Except difference between each array element SpanMany and input Span (s[i] \ input). Returns the elements of SpanMany, where the time interval remains after the Except operation with input. Before returning the final result is sorted and merged.

func (*SpanMany) ExceptionIfIntersection

func (s *SpanMany) ExceptionIfIntersection(input SpanMany, offset ...time.Duration) SpanMany

offset - possible deviation from the time interval

func (*SpanMany) ExceptionIfNotContains added in v0.1.0

func (s *SpanMany) ExceptionIfNotContains(input SpanMany, offset ...time.Duration) SpanMany

ExceptionIfNotContains excludes periods from SpanMany if it does not contain any interval with another SpanMany.

func (*SpanMany) ExceptionIfNotEqual

func (s *SpanMany) ExceptionIfNotEqual(input SpanMany, offset ...time.Duration) SpanMany

offset - possible deviation from the time interval

func (*SpanMany) Intersection

func (s *SpanMany) Intersection(input Span) SpanMany

Intersection intersecting time slots (SpanMany) with one time slot (Span).

func (*SpanMany) IsContains added in v0.1.0

func (s *SpanMany) IsContains(input Span, offset ...time.Duration) bool

IsContains checking for contains of SpanMany of time intervals with one interval. If there is at least one match, return true.

func (*SpanMany) IsIntersection

func (s *SpanMany) IsIntersection(input Span, offset ...time.Duration) bool

offset - possible deviation from the time interval.

func (*SpanMany) Sort

func (s *SpanMany) Sort(st ...SortType)

st - sorting options: Ascending sort Ascending (default) Descending sort descending

func (*SpanMany) Spans

func (s *SpanMany) Spans() []Span

Spans get an array of intervals.

func (*SpanMany) String

func (s *SpanMany) String() string

String implementation interface stringer for SpanMany.

func (*SpanMany) Union

func (s *SpanMany) Union(input ...SpanMany) SpanMany

Union concatenation SpanMany of array SpanMany.

Jump to

Keyboard shortcuts

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