time: let time.parse_rfc3339('2015-01-06T15:47:32.080254511Z') succeed (dockerd timestamps, Go's RFC3339Nano).

master
Delyan Angelov 2022-05-08 13:56:50 +03:00
parent a0a3499bdc
commit 084f2867b6
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
2 changed files with 58 additions and 13 deletions

View File

@ -193,11 +193,32 @@ fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
hour_ := 0 hour_ := 0
minute_ := 0 minute_ := 0
second_ := 0 second_ := 0
microsecond_ := 0 mut microsecond_ := 0
mut nanosecond_ := 0
plus_min_z := `a` plus_min_z := `a`
offset_hour := 0 offset_hour := 0
offset_minute := 0 offset_minute := 0
mut count := unsafe { mut count := 0
count = unsafe {
C.sscanf(&char(s.str), c'%2d:%2d:%2d.%9d%c', &hour_, &minute_, &second_, &nanosecond_,
&char(&plus_min_z))
}
if count == 5 && plus_min_z == `Z` {
// normalise the nanoseconds:
mut ndigits := 0
if mut pos := s.index('.') {
pos++
for ; pos < s.len && s[pos].is_digit(); pos++ {
ndigits++
}
}
for ndigits < 9 {
nanosecond_ *= 10
ndigits++
}
microsecond_ = nanosecond_ / 1000
} else {
count = unsafe {
C.sscanf(&char(s.str), c'%2d:%2d:%2d.%6d%c%2d:%2d', &hour_, &minute_, &second_, C.sscanf(&char(s.str), c'%2d:%2d:%2d.%6d%c%2d:%2d', &hour_, &minute_, &second_,
&microsecond_, &char(&plus_min_z), &offset_hour, &offset_minute) &microsecond_, &char(&plus_min_z), &offset_hour, &offset_minute)
} }
@ -212,6 +233,7 @@ fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
if count < 4 { if count < 4 {
return error_invalid_time(10) return error_invalid_time(10)
} }
}
is_local_time := plus_min_z == `a` && count == 4 is_local_time := plus_min_z == `a` && count == 4
is_utc := plus_min_z == `Z` && count == 5 is_utc := plus_min_z == `Z` && count == 5
if !(count == 7 || is_local_time || is_utc) { if !(count == 7 || is_local_time || is_utc) {

View File

@ -3,6 +3,7 @@ import time
fn test_parse() { fn test_parse() {
s := '2018-01-27 12:48:34' s := '2018-01-27 12:48:34'
t := time.parse(s) or { t := time.parse(s) or {
eprintln('> failing format: $s | err: $err')
assert false assert false
return return
} }
@ -23,6 +24,7 @@ fn test_parse_invalid() {
fn test_parse_rfc2822() { fn test_parse_rfc2822() {
s1 := 'Thu, 12 Dec 2019 06:07:45 GMT' s1 := 'Thu, 12 Dec 2019 06:07:45 GMT'
t1 := time.parse_rfc2822(s1) or { t1 := time.parse_rfc2822(s1) or {
eprintln('> failing format: $s1 | err: $err')
assert false assert false
return return
} }
@ -31,6 +33,7 @@ fn test_parse_rfc2822() {
assert t1.unix == 1576130865 assert t1.unix == 1576130865
s2 := 'Thu 12 Dec 2019 06:07:45 +0800' s2 := 'Thu 12 Dec 2019 06:07:45 +0800'
t2 := time.parse_rfc2822(s2) or { t2 := time.parse_rfc2822(s2) or {
eprintln('> failing format: $s2 | err: $err')
assert false assert false
return return
} }
@ -67,6 +70,7 @@ fn test_parse_iso8601() {
] ]
for i, format in formats { for i, format in formats {
t := time.parse_iso8601(format) or { t := time.parse_iso8601(format) or {
eprintln('>>> failing format: $format | err: $err')
assert false assert false
continue continue
} }
@ -90,6 +94,7 @@ fn test_parse_iso8601() {
fn test_parse_iso8601_local() { fn test_parse_iso8601_local() {
format := '2020-06-05T15:38:06.015959' format := '2020-06-05T15:38:06.015959'
t := time.parse_iso8601(format) or { t := time.parse_iso8601(format) or {
eprintln('> failing format: $format | err: $err')
assert false assert false
return return
} }
@ -127,6 +132,7 @@ fn test_parse_iso8601_invalid() {
fn test_parse_iso8601_date_only() { fn test_parse_iso8601_date_only() {
format := '2020-06-05' format := '2020-06-05'
t := time.parse_iso8601(format) or { t := time.parse_iso8601(format) or {
eprintln('> failing format: $format | err: $err')
assert false assert false
return return
} }
@ -161,3 +167,20 @@ fn test_invalid_dates_should_error_during_parse() {
check_invalid_date('2008-12-01 00:60:00') check_invalid_date('2008-12-01 00:60:00')
check_invalid_date('2008-12-01 00:01:60') check_invalid_date('2008-12-01 00:01:60')
} }
fn test_parse_rfc3339() {
pairs := [
['2015-01-06T15:47:32.080254511Z', '2015-01-06 15:47:32.080254'],
['2015-01-06T15:47:32.072697474Z', '2015-01-06 15:47:32.072697'],
]
for pair in pairs {
input, expected := pair[0], pair[1]
res := time.parse_rfc3339(input) or {
eprintln('>>> failing input: $input | err: $err')
assert false
return
}
output := res.format_ss_micro()
assert expected == output
}
}