Skip to content

Commit

Permalink
Added TimeSpan.Format and MarshalText methods, compatible with RFC5545.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rick Beton committed Jul 17, 2018
1 parent b004bed commit a2b74d5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.so

# Folders
.idea/
_obj/
_test/
vendor/
Expand Down
1 change: 1 addition & 0 deletions timespan/daterange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ func TestDurationInZoneWithDaylightSaving(t *testing.T) {
}

func isEq(t *testing.T, a, b interface{}, msg ...interface{}) {
t.Helper()
if a != b {
sa := make([]string, len(msg))
for i, m := range msg {
Expand Down
23 changes: 23 additions & 0 deletions timespan/timespan.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"github.com/rickb777/date"
"time"
"github.com/rickb777/date/period"
)

// TimestampFormat is a simple format for date & time, "2006-01-02 15:04:05".
Expand Down Expand Up @@ -144,3 +145,25 @@ func (ts TimeSpan) Merge(other TimeSpan) TimeSpan {
return NewTimeSpan(ts.mark, other.End())
}
}

// RFC5545DateTimeLayout is the format string used by iCalendar (RFC5545). Note
// that "Z" is to be appended when the time is UTC.
const RFC5545DateTimeLayout = "20060102T150405"

func (ts TimeSpan) Format() string {
format := RFC5545DateTimeLayout
if ts.mark.Location().String() == "UTC" {
format = RFC5545DateTimeLayout + "Z"
}
s := ts.Start()
e := ts.End()
p := period.Between(s, e)
return fmt.Sprintf("%s/%s", s.Format(format), p)
}

// MarshalText formats the timespan as a string. This implements
// then encoding.TextMarshaler interface.
func (ts TimeSpan) MarshalText() (text []byte, err error) {
s := ts.Format()
return []byte(s), nil
}
23 changes: 23 additions & 0 deletions timespan/timespan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,29 @@ func TestTSString(t *testing.T) {
isEq(t, s, "24h0m0s from 2015-03-27 00:00:00 to 2015-03-28 00:00:00")
}

func TestTSFormat(t *testing.T) {
// use Berlin, which is UTC-1
berlin, _ := time.LoadLocation("Europe/Berlin")
t0 := time.Date(2015, 3, 27, 10, 13, 14, 0, time.UTC)

cases := []struct{
start time.Time
duration time.Duration
exp string
}{
{t0, time.Hour, "20150327T101314Z/PT1H"},
{t0.In(berlin), time.Minute, "20150327T111314/PT1M"},
}

for _, c := range cases {
ts := TimeSpan{c.start, c.duration}
b, err := ts.MarshalText()
isEq(t, ts.Format(), c.exp)
isEq(t, err, nil)
isEq(t, string(b), c.exp)
}
}

func TestTSContains(t *testing.T) {
ts := NewTimeSpan(t0327, t0329)
isEq(t, ts.Contains(t0327.Add(minusOneNano)), false)
Expand Down

0 comments on commit a2b74d5

Please sign in to comment.