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,24 +193,46 @@ fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
hour_ := 0
minute_ := 0
second_ := 0
microsecond_ := 0
mut microsecond_ := 0
mut nanosecond_ := 0
plus_min_z := `a`
offset_hour := 0
offset_minute := 0
mut count := unsafe {
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)
mut count := 0
count = unsafe {
C.sscanf(&char(s.str), c'%2d:%2d:%2d.%9d%c', &hour_, &minute_, &second_, &nanosecond_,
&char(&plus_min_z))
}
// Missread microsecond ([Sec Hour Minute].len == 3 < 4)
if count < 4 {
count = unsafe {
C.sscanf(&char(s.str), c'%2d:%2d:%2d%c%2d:%2d', &hour_, &minute_, &second_,
&char(&plus_min_z), &offset_hour, &offset_minute)
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_,
&microsecond_, &char(&plus_min_z), &offset_hour, &offset_minute)
}
// Missread microsecond ([Sec Hour Minute].len == 3 < 4)
if count < 4 {
count = unsafe {
C.sscanf(&char(s.str), c'%2d:%2d:%2d%c%2d:%2d', &hour_, &minute_, &second_,
&char(&plus_min_z), &offset_hour, &offset_minute)
}
count++ // Increment count because skipped microsecond
}
if count < 4 {
return error_invalid_time(10)
}
count++ // Increment count because skipped microsecond
}
if count < 4 {
return error_invalid_time(10)
}
is_local_time := plus_min_z == `a` && count == 4
is_utc := plus_min_z == `Z` && count == 5

View File

@ -3,6 +3,7 @@ import time
fn test_parse() {
s := '2018-01-27 12:48:34'
t := time.parse(s) or {
eprintln('> failing format: $s | err: $err')
assert false
return
}
@ -23,6 +24,7 @@ fn test_parse_invalid() {
fn test_parse_rfc2822() {
s1 := 'Thu, 12 Dec 2019 06:07:45 GMT'
t1 := time.parse_rfc2822(s1) or {
eprintln('> failing format: $s1 | err: $err')
assert false
return
}
@ -31,6 +33,7 @@ fn test_parse_rfc2822() {
assert t1.unix == 1576130865
s2 := 'Thu 12 Dec 2019 06:07:45 +0800'
t2 := time.parse_rfc2822(s2) or {
eprintln('> failing format: $s2 | err: $err')
assert false
return
}
@ -67,6 +70,7 @@ fn test_parse_iso8601() {
]
for i, format in formats {
t := time.parse_iso8601(format) or {
eprintln('>>> failing format: $format | err: $err')
assert false
continue
}
@ -90,6 +94,7 @@ fn test_parse_iso8601() {
fn test_parse_iso8601_local() {
format := '2020-06-05T15:38:06.015959'
t := time.parse_iso8601(format) or {
eprintln('> failing format: $format | err: $err')
assert false
return
}
@ -127,6 +132,7 @@ fn test_parse_iso8601_invalid() {
fn test_parse_iso8601_date_only() {
format := '2020-06-05'
t := time.parse_iso8601(format) or {
eprintln('> failing format: $format | err: $err')
assert false
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: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
}
}