Skip to content
Snippets Groups Projects
Commit 2bc5729e authored by Jan Semmelink's avatar Jan Semmelink
Browse files

Module to figure out time periods

parent c7a00ac2
No related branches found
No related tags found
1 merge request!8More cleanup, remove clutter, add to api-logs, sqs-logs possible, action list in api-logs, runtime control possible
package logs
import (
"time"
)
type Period struct {
Start time.Time `json:"start_time"`
End time.Time `json:"end_time"`
}
func (p Period) Duration() time.Duration {
return p.End.Sub(p.Start)
}
type Periods []Period
func NewPeriods(start time.Time, end time.Time) Periods {
if end.Before(start) {
return []Period{}
}
return []Period{{Start: start, End: end}}
}
func (ps Periods) Without(p Period) Periods {
if len(ps) == 0 {
return ps //nothing left to take from
}
if p.End.Before(ps[0].Start) {
return ps //before first period
}
if p.Start.After(ps[len(ps)-1].End) {
return ps //after last period
}
//logger.Debugf("Start: %+v", ps)
nextIndex := 0
for nextIndex < len(ps) && ps[nextIndex].End.Before(p.Start) {
//logger.Debugf("skip[%d]: %s > %s", nextIndex, p.Start, ps[nextIndex].End)
nextIndex++
}
toDelete := []int{}
for nextIndex < len(ps) && ps[nextIndex].End.Before(p.End) {
if ps[nextIndex].Start.Before(p.Start) {
//trim tail
//logger.Debugf("tail[%d] %s->%s", nextIndex, ps[nextIndex].End, p.Start)
ps[nextIndex].End = p.Start
} else {
//delete this period completely and move to next
toDelete = append(toDelete, nextIndex)
//logger.Debugf("delete[%d] %s..%s", nextIndex, ps[nextIndex].Start, ps[nextIndex].End)
}
nextIndex++
}
if nextIndex < len(ps) && ps[nextIndex].End.After(p.End) {
if ps[nextIndex].Start.Before(p.Start) {
//remove part of this period
ps = append(ps, Period{Start: p.End, End: ps[nextIndex].End})
ps[nextIndex].End = p.Start
//logger.Debugf("split[%d]", nextIndex)
} else {
if ps[nextIndex].Start.Before(p.End) {
//trim head of period to start after removed peroid, then stop
//logger.Debugf("head[%d] %s->%s", nextIndex, ps[nextIndex].Start, p.End)
ps[nextIndex].Start = p.End
}
}
}
//delete selected periods completely
newPS := []Period{}
for i, p := range ps {
if len(toDelete) > 0 && i == toDelete[0] {
toDelete = toDelete[1:]
} else {
newPS = append(newPS, p)
}
}
//logger.Debugf("final: %+v", newPS)
return newPS
}
//Span is (last.end - first.start)
func (ps Periods) Span() time.Duration {
if len(ps) > 0 {
return ps[len(ps)-1].End.Sub(ps[0].Start)
}
return time.Duration(0)
}
//Duration is sum of all period durations
func (ps Periods) Duration() time.Duration {
dur := time.Duration(0)
for _, p := range ps {
dur += p.Duration()
}
return dur
}
//Gaps is (Span - Duration), i.e. time between periods
func (ps Periods) Gaps() time.Duration {
return ps.Span() - ps.Duration()
}
package logs_test
import (
"testing"
"time"
"gitlab.com/uafrica/go-utils/logger"
"gitlab.com/uafrica/go-utils/logs"
)
func TestPeriods(t *testing.T) {
logger.SetGlobalFormat(logger.NewConsole())
logger.SetGlobalLevel(logger.LevelDebug)
t0 := time.Date(2021, 01, 01, 0, 0, 0, 0, time.Now().Location())
ps := logs.NewPeriods(t0, t0.Add(time.Hour))
t.Log(ps)
//ps: 0..60
//split[0]
ps1 := ps.Without(logs.Period{Start: t0.Add(time.Minute * 5), End: t0.Add(time.Minute * 10)})
t.Log(ps1)
//-(5..10) -> ps1: 0..5, 10..60
//split[1]
ps2 := ps1.Without(logs.Period{Start: t0.Add(time.Minute * 15), End: t0.Add(time.Minute * 20)})
t.Log(ps2)
//-(15..20) -> ps1: 0..5, 10..15, 20..60
//trim head[2]
ps3 := ps2.Without(logs.Period{Start: t0.Add(time.Minute * 18), End: t0.Add(time.Minute * 21)})
t.Log(ps3)
//-(18..21) -> ps1: 0..5, 10..15, 21..60
//trim tail[1]
ps4 := ps3.Without(logs.Period{Start: t0.Add(time.Minute * 14), End: t0.Add(time.Minute * 19)})
t.Log(ps4)
//-(14..19) -> ps1: 0..5, 10..14, 21..60
//tail, delete, head
ps5 := ps4.Without(logs.Period{Start: t0.Add(time.Minute * 4), End: t0.Add(time.Minute * 22)})
t.Log(ps5)
//-(4..22) -> ps1: 0..4, 22..60
//over start
ps6 := ps5.Without(logs.Period{Start: t0.Add(-time.Minute * 1), End: t0.Add(time.Minute * 2)})
t.Log(ps6)
//-(-1..2) -> ps1: 2..4, 22..60
//over end
ps7 := ps6.Without(logs.Period{Start: t0.Add(time.Minute * 50), End: t0.Add(time.Minute * 120)})
t.Log(ps7)
//-(50..120) -> ps1: 2..4, 22..50
//all
ps8 := ps7.Without(logs.Period{Start: t0.Add(time.Minute * 0), End: t0.Add(time.Minute * 120)})
t.Log(ps8)
//-(0..120) -> ps1: nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment