Skip to content

Commit

Permalink
Merge pull request #32 from gochore/dev
Browse files Browse the repository at this point in the history
feat: add method Truncate & Duration
  • Loading branch information
wolfogre authored Feb 3, 2021
2 parents c679074 + 1a23847 commit 1abafc5
Show file tree
Hide file tree
Showing 2 changed files with 170 additions and 9 deletions.
47 changes: 38 additions & 9 deletions interval.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type Interval struct {
NotAfter *time.Time
}

// Contain return if time t is in the interval
// Contain returns if time t is in the interval
func (i Interval) Contain(t time.Time) bool {
if i.NotAfter != nil && t.After(*i.NotAfter) {
return false
Expand Down Expand Up @@ -46,23 +46,23 @@ func (i Interval) EndAt(t time.Time) Interval {
return i.BeforeOrEqual(t)
}

// BeforeOrEqual return a new Interval which not before t
// BeforeOrEqual returns a new Interval which not before t
func (i Interval) BeforeOrEqual(t time.Time) Interval {
return Interval{
NotBefore: i.NotBefore,
NotAfter: &t,
}
}

// AfterOrEqual return a new Interval which not after t
// AfterOrEqual returns a new Interval which not after t
func (i Interval) AfterOrEqual(t time.Time) Interval {
return Interval{
NotBefore: &t,
NotAfter: i.NotAfter,
}
}

// Before return a new Interval which before t
// Before returns a new Interval which before t
func (i Interval) Before(t time.Time) Interval {
t = t.Add(-1)
return Interval{
Expand All @@ -71,7 +71,7 @@ func (i Interval) Before(t time.Time) Interval {
}
}

// After return a new Interval which after t
// After returns a new Interval which after t
func (i Interval) After(t time.Time) Interval {
t = t.Add(1)
return Interval{
Expand All @@ -80,6 +80,35 @@ func (i Interval) After(t time.Time) Interval {
}
}

// Truncate returns the result of rounding interval down to a multiple of d (since the zero time).
func (i Interval) Truncate(d time.Duration) Interval {
if i.NotBefore != nil {
t := (*i.NotBefore).Truncate(d)
if t.Before(*i.NotBefore) {
t = t.Add(d)
}
i.NotBefore = &t
}
if i.NotAfter != nil {
t := (*i.NotAfter).Truncate(d)
i.NotAfter = &t
}
return i
}

// Duration returns the duration NotAfter - NotBefore,
// returns 0 if NotAfter is before or equal NotBefore,
// returns -1 if NotAfter or NotBefore if nil.
func (i Interval) Duration() time.Duration {
if i.NotBefore == nil || i.NotAfter == nil {
return -1
}
if !(*i.NotAfter).After(*i.NotBefore) {
return 0
}
return (*i.NotAfter).Sub(*i.NotBefore)
}

// BeginAt is alias of AfterOrEqual
func BeginAt(t time.Time) Interval {
return AfterOrEqual(t)
Expand All @@ -90,29 +119,29 @@ func EndAt(t time.Time) Interval {
return BeforeOrEqual(t)
}

// BeforeOrEqual return a new Interval which not before t
// BeforeOrEqual returns a new Interval which not before t
func BeforeOrEqual(t time.Time) Interval {
return Interval{
NotAfter: &t,
}
}

// AfterOrEqual return a new Interval which not after t
// AfterOrEqual returns a new Interval which not after t
func AfterOrEqual(t time.Time) Interval {
return Interval{
NotBefore: &t,
}
}

// Before return a new Interval which before t
// Before returns a new Interval which before t
func Before(t time.Time) Interval {
t = t.Add(-1)
return Interval{
NotAfter: &t,
}
}

// After return a new Interval which after t
// After returns a new Interval which after t
func After(t time.Time) Interval {
t = t.Add(1)
return Interval{
Expand Down
132 changes: 132 additions & 0 deletions interval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,24 @@ package timeseq

import (
"fmt"
"reflect"
"testing"
"time"
)

func parseTime(s string) time.Time {
ret, err := time.Parse(time.RFC3339, s)
if err != nil {
panic(err)
}
return ret
}

func parseTimeP(s string) *time.Time {
ret := parseTime(s)
return &ret
}

func TestInterval_Contain(t *testing.T) {
now := time.Now()
type args struct {
Expand Down Expand Up @@ -219,3 +233,121 @@ func TestInterval_Format(t *testing.T) {
})
}
}

func TestInterval_Truncate(t *testing.T) {
type fields struct {
NotBefore *time.Time
NotAfter *time.Time
}
type args struct {
d time.Duration
}
tests := []struct {
name string
fields fields
args args
want Interval
}{
{
name: "regular",
fields: fields{
NotBefore: parseTimeP("2021-02-02T20:34:10+08:00"),
NotAfter: parseTimeP("2021-02-02T21:34:10+08:00"),
},
args: args{
d: time.Minute,
},
want: Interval{
NotBefore: parseTimeP("2021-02-02T20:35:00+08:00"),
NotAfter: parseTimeP("2021-02-02T21:34:00+08:00"),
},
},
{
name: "unchanged",
fields: fields{
NotBefore: parseTimeP("2021-02-02T20:35:00+08:00"),
NotAfter: parseTimeP("2021-02-02T21:34:00+08:00"),
},
args: args{
d: time.Minute,
},
want: Interval{
NotBefore: parseTimeP("2021-02-02T20:35:00+08:00"),
NotAfter: parseTimeP("2021-02-02T21:34:00+08:00"),
},
},
{
name: "nil",
fields: fields{
NotBefore: nil,
NotAfter: nil,
},
args: args{
d: time.Minute,
},
want: Interval{
NotBefore: nil,
NotAfter: nil,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
i := Interval{
NotBefore: tt.fields.NotBefore,
NotAfter: tt.fields.NotAfter,
}
if got := i.Truncate(tt.args.d); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Truncate() = %v, want %v", got, tt.want)
}
})
}
}

func TestInterval_Duration(t *testing.T) {
type fields struct {
NotBefore *time.Time
NotAfter *time.Time
}
tests := []struct {
name string
fields fields
want time.Duration
}{
{
name: "regular",
fields: fields{
NotBefore: parseTimeP("2021-02-02T20:35:00+08:00"),
NotAfter: parseTimeP("2021-02-02T20:36:00+08:00"),
},
want: time.Minute,
},
{
name: "nil",
fields: fields{
NotBefore: nil,
NotAfter: parseTimeP("2021-02-02T20:36:00+08:00"),
},
want: -1,
},
{
name: "zero",
fields: fields{
NotBefore: parseTimeP("2021-02-02T20:36:00+08:00"),
NotAfter: parseTimeP("2021-02-02T20:36:00+08:00"),
},
want: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
i := Interval{
NotBefore: tt.fields.NotBefore,
NotAfter: tt.fields.NotAfter,
}
if got := i.Duration(); got != tt.want {
t.Errorf("Duration() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 1abafc5

Please sign in to comment.