From 49a083fe7918ec9f91b2e440b3f4993176282e85 Mon Sep 17 00:00:00 2001 From: Takahiro Yaota Date: Sun, 29 Nov 2020 17:38:14 +0900 Subject: [PATCH] time: improve parse_iso8601 (#7006) --- vlib/time/parse.v | 18 ++++++++++++------ vlib/time/parse_test.v | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/vlib/time/parse.v b/vlib/time/parse.v index 1bdf74074e..92e82e6389 100644 --- a/vlib/time/parse.v +++ b/vlib/time/parse.v @@ -62,20 +62,22 @@ pub fn parse_iso8601(s string) ?Time { second := 0 mic_second := 0 time_char := `a` - plus_min := `a` + plus_min_z := `a` offset_hour := 0 offset_min := 0 count := unsafe {C.sscanf(charptr(s.str), '%4d-%2d-%2d%c%2d:%2d:%2d.%6d%c%2d:%2d', - &year, &month, &day, charptr(&time_char), &hour, &minute, &second, &mic_second, charptr(&plus_min), &offset_hour, + &year, &month, &day, charptr(&time_char), &hour, &minute, &second, &mic_second, charptr(&plus_min_z), &offset_hour, &offset_min)} - if count != 11 { + is_local_time := plus_min_z == `a` && count == 8 + is_utc := plus_min_z == `Z` && count == 9 + if count != 11 && !is_local_time && !is_utc { return error('Invalid 8601 format') } if time_char != `T` && time_char != ` ` { return error('Invalid 8601 format, expected space or `T` as time separator') } - if plus_min != `+` && plus_min != `-` { - return error('Invalid 8601 format, expected `+` or `-` as time separator') + if plus_min_z != `+` && plus_min_z != `-` && plus_min_z != `Z` && !is_local_time { + return error('Invalid 8601 format, expected `Z` or `+` or `-` as time separator') } mut t := new_time(Time{ year: year @@ -86,6 +88,10 @@ pub fn parse_iso8601(s string) ?Time { second: second microsecond: mic_second }) + if is_local_time { + return to_local_time(t) + } + mut unix_time := t.unix mut unix_offset := int(0) if offset_hour > 0 { @@ -95,7 +101,7 @@ pub fn parse_iso8601(s string) ?Time { unix_offset += 60 * offset_min } if unix_offset != 0 { - if plus_min == `+` { + if plus_min_z == `+` { unix_time -= u64(unix_offset) } else { unix_time += u64(unix_offset) diff --git a/vlib/time/parse_test.v b/vlib/time/parse_test.v index 7c438502d3..ccc8ecf7d8 100644 --- a/vlib/time/parse_test.v +++ b/vlib/time/parse_test.v @@ -45,6 +45,25 @@ fn test_parse_rfc2822_invalid() { assert false } +fn test_iso8601_parse_utc() { + format_utc := '2020-06-05T15:38:06.015959Z' + t_utc := time.parse_iso8601(format_utc) or {panic(err)} + + assert t_utc.year == 2020 + assert t_utc.month == 6 + assert t_utc.day == 5 + +} + +fn test_iso8601_parse_loacl() { + format_utc := '2020-06-05T15:38:06.015959' + t_utc := time.parse_iso8601(format_utc) or {panic(err)} + + assert t_utc.year == 2020 + assert t_utc.month == 6 + assert t_utc.day == 5 +} + fn test_iso8601_parse_utc_diff() { format_utc := '2020-06-05T15:38:06.015959+00:00' format_cest := '2020-06-05T15:38:06.015959+02:00' @@ -68,4 +87,4 @@ fn test_iso8601_parse_utc_diff() { assert t_cest.second == 6 assert t_utc.microsecond == 15959 assert t_cest.microsecond == 15959 -} \ No newline at end of file +}