Add TimeOfDay type.
This commit is contained in:
parent
17abe5294a
commit
7469efd5ff
@ -3,6 +3,7 @@ package soap
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
@ -52,9 +53,43 @@ var dateFmts = []string{"2006-01-02", "20060102"}
|
|||||||
|
|
||||||
func UnmarshalDate(s string) (time.Time, error) {
|
func UnmarshalDate(s string) (time.Time, error) {
|
||||||
for _, f := range dateFmts {
|
for _, f := range dateFmts {
|
||||||
if t, err := time.Parse(f, s); err == nil {
|
if t, err := time.ParseInLocation(f, s, time.Local); err == nil {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return time.Time{}, fmt.Errorf("soap date: value %q is not in a recognized date format", s)
|
return time.Time{}, fmt.Errorf("soap date: value %q is not in a recognized date format", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TimeOfDay is used in cases where SOAP "time" or "time.tz" is used.
|
||||||
|
type TimeOfDay struct {
|
||||||
|
// Duration of time since midnight.
|
||||||
|
FromMidnight time.Duration
|
||||||
|
|
||||||
|
// TimeZone is present only if time.tz is used. It is otherwise ignored.
|
||||||
|
TimeZone *time.Location
|
||||||
|
}
|
||||||
|
|
||||||
|
func MarshalTimeOfDay(v TimeOfDay) (string, error) {
|
||||||
|
d := int64(v.FromMidnight / time.Second)
|
||||||
|
hour := d / 3600
|
||||||
|
d = d % 3600
|
||||||
|
minute := d / 60
|
||||||
|
second := d % 60
|
||||||
|
|
||||||
|
return fmt.Sprintf("%02d:%02d:%02d", hour, minute, second), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var timeRegexp = regexp.MustCompile(`^(\d\d)(?::?(\d\d)(?::?(\d\d))?)?$`)
|
||||||
|
|
||||||
|
func UnmarshalTimeOfDay(s string) (TimeOfDay, error) {
|
||||||
|
parts := timeRegexp.FindStringSubmatch(s)
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return TimeOfDay{}, fmt.Errorf("soap time: value %q is not in ISO8601 time format", s)
|
||||||
|
}
|
||||||
|
parts = parts[1:]
|
||||||
|
var iParts [3]int64
|
||||||
|
for i, pStr := range parts {
|
||||||
|
iParts[i], _ = strconv.ParseInt(pStr, 10, 64)
|
||||||
|
}
|
||||||
|
return TimeOfDay{time.Duration(iParts[0]*3600+iParts[1]*60+iParts[2]) * time.Second, nil}, nil
|
||||||
|
}
|
||||||
|
@ -57,6 +57,20 @@ func (v DateTest) Equal(result interface{}) bool {
|
|||||||
return v.Time.Equal(result.(time.Time))
|
return v.Time.Equal(result.(time.Time))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TimeOfDayTest struct {
|
||||||
|
TimeOfDay
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v TimeOfDayTest) Marshal() (string, error) {
|
||||||
|
return MarshalTimeOfDay(v.TimeOfDay)
|
||||||
|
}
|
||||||
|
func (v TimeOfDayTest) Unmarshal(s string) (interface{}, error) {
|
||||||
|
return UnmarshalTimeOfDay(s)
|
||||||
|
}
|
||||||
|
func (v TimeOfDayTest) Equal(result interface{}) bool {
|
||||||
|
return v.TimeOfDay == result.(TimeOfDay)
|
||||||
|
}
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
tests := []testCase{
|
tests := []testCase{
|
||||||
// Fixed14_4
|
// Fixed14_4
|
||||||
@ -78,11 +92,27 @@ func Test(t *testing.T) {
|
|||||||
{str: "", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true},
|
{str: "", value: CharTest(0), wantMarshalErr: true, wantUnmarshalErr: true},
|
||||||
|
|
||||||
// Date
|
// Date
|
||||||
{str: "2013-10-08", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, time.UTC)}},
|
{str: "2013-10-08", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, time.Local)}},
|
||||||
{str: "20131008", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, time.UTC)}, noMarshal: true},
|
{str: "20131008", value: DateTest{time.Date(2013, 10, 8, 0, 0, 0, 0, time.Local)}, noMarshal: true},
|
||||||
{str: "2013-10-08T10:30:50", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true},
|
{str: "2013-10-08T10:30:50", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
{str: "", value: DateTest{}, wantMarshalErr: true, wantUnmarshalErr: true, noMarshal: true},
|
{str: "", value: DateTest{}, wantMarshalErr: true, wantUnmarshalErr: true, noMarshal: true},
|
||||||
{str: "-1", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true},
|
{str: "-1", value: DateTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
|
|
||||||
|
// Time
|
||||||
|
{str: "00:00:00", value: TimeOfDayTest{TimeOfDay{0, nil}}},
|
||||||
|
{str: "000000", value: TimeOfDayTest{TimeOfDay{0, nil}}, noMarshal: true},
|
||||||
|
{str: "01:02:03", value: TimeOfDayTest{TimeOfDay{(1*3600 + 2*60 + 3) * time.Second, nil}}},
|
||||||
|
{str: "010203", value: TimeOfDayTest{TimeOfDay{(1*3600 + 2*60 + 3) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "23:59:59", value: TimeOfDayTest{TimeOfDay{(23*3600 + 59*60 + 59) * time.Second, nil}}},
|
||||||
|
{str: "235959", value: TimeOfDayTest{TimeOfDay{(23*3600 + 59*60 + 59) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "01:02", value: TimeOfDayTest{TimeOfDay{(1*3600 + 2*60) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "0102", value: TimeOfDayTest{TimeOfDay{(1*3600 + 2*60) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "01", value: TimeOfDayTest{TimeOfDay{(1 * 3600) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "01", value: TimeOfDayTest{TimeOfDay{(1 * 3600) * time.Second, nil}}, noMarshal: true},
|
||||||
|
{str: "foo 01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
|
{str: "foo\n01:02:03", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
|
{str: "01:02:03 foo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
|
{str: "01:02:03\nfoo", value: TimeOfDayTest{}, wantUnmarshalErr: true, noMarshal: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
Loading…
Reference in New Issue
Block a user