Added code that accounts for the 'Z' timezone separator in the ParseTimestamp func. (#1073)

Co-authored-by: Stephan van Zwienen <s.vanzwienen@zwinq.com>
pull/1080/head
Stephan 2022-04-13 03:12:02 +02:00 committed by GitHub
parent da9184484e
commit 006a3f4923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 2 deletions

View File

@ -422,7 +422,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
if remainderIdx < len(str) && str[remainderIdx] == '.' {
fracStart := remainderIdx + 1
fracOff := strings.IndexAny(str[fracStart:], "-+ ")
fracOff := strings.IndexAny(str[fracStart:], "-+Z ")
if fracOff < 0 {
fracOff = len(str) - fracStart
}
@ -432,7 +432,7 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
remainderIdx += fracOff + 1
}
if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') {
// time zone separator is always '-' or '+' (UTC is +00)
// time zone separator is always '-' or '+' or 'Z' (UTC is +00)
var tzSign int
switch c := str[tzStart]; c {
case '-':
@ -454,7 +454,11 @@ func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, erro
remainderIdx += 3
}
tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec)
} else if tzStart < len(str) && str[tzStart] == 'Z' {
// time zone Z separator indicates UTC is +00
remainderIdx += 1
}
var isoYear int
if isBC {

View File

@ -828,6 +828,43 @@ func TestAppendEscapedTextExistingBuffer(t *testing.T) {
}
}
var formatAndParseTimestamp = []struct {
time time.Time
expected string
}{
{time.Time{}, "0001-01-01 00:00:00Z"},
{time.Date(2001, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 0)), "2001-02-03 04:05:06.123456789Z"},
{time.Date(2001, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 2*60*60)), "2001-02-03 04:05:06.123456789+02:00"},
{time.Date(2001, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", -6*60*60)), "2001-02-03 04:05:06.123456789-06:00"},
{time.Date(2001, time.February, 3, 4, 5, 6, 0, time.FixedZone("", -(7*60*60+30*60+9))), "2001-02-03 04:05:06-07:30:09"},
{time.Date(1, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 0)), "0001-02-03 04:05:06.123456789Z"},
{time.Date(1, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 2*60*60)), "0001-02-03 04:05:06.123456789+02:00"},
{time.Date(1, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", -6*60*60)), "0001-02-03 04:05:06.123456789-06:00"},
{time.Date(0, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 0)), "0001-02-03 04:05:06.123456789Z BC"},
{time.Date(0, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", 2*60*60)), "0001-02-03 04:05:06.123456789+02:00 BC"},
{time.Date(0, time.February, 3, 4, 5, 6, 123456789, time.FixedZone("", -6*60*60)), "0001-02-03 04:05:06.123456789-06:00 BC"},
{time.Date(1, time.February, 3, 4, 5, 6, 0, time.FixedZone("", -(7*60*60+30*60+9))), "0001-02-03 04:05:06-07:30:09"},
{time.Date(0, time.February, 3, 4, 5, 6, 0, time.FixedZone("", -(7*60*60+30*60+9))), "0001-02-03 04:05:06-07:30:09 BC"},
}
func TestFormatAndParseTimestamp(t *testing.T) {
for _, val := range formatAndParseTimestamp {
formattedTime := FormatTimestamp(val.time)
parsedTime, err := ParseTimestamp(nil, string(formattedTime))
if err != nil {
t.Errorf("invalid parsing, err: %v", err.Error())
}
if val.time.UTC() != parsedTime.UTC() {
t.Errorf("invalid parsing from formatted timestamp, got %v; expected %v", parsedTime.String(), val.time.String())
}
}
}
func BenchmarkAppendEscapedText(b *testing.B) {
longString := ""
for i := 0; i < 100; i++ {