Skip to content

Commit a72530b

Browse files
haakon-eKristofferC
authored andcommitted
fix: TOML parsing of fractional seconds (#59999)
fix a bug in which parsing the digits after the decimal point of a (date-)time like "00:00:00.12" were interpreted as "12 milliseconds" instead of "0.12 seconds". Now, the fractional part is correctly parsed as a fraction of a second, then correctly converted to milliseconds. As before, only the first three digits after the decimal point are considered. Closes #59997 --- With a local build of this PR, the example from the above issue now evaluates to: ```julia julia> t2 = TOML.parse("""time = 00:00:00.2""") Dict{String, Any} with 1 entry: "time" => 00:00:00.2 julia> millisecond(t2["time"]) 200 ``` (cherry picked from commit 906d64e)
1 parent aec2423 commit a72530b

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

base/toml_parser.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,7 @@ function _parse_local_time(l::Parser, skip_hour=false)::Err{NTuple{4, Int64}}
11101110
second in 0:59 || return ParserError(ErrParsingDateTime)
11111111

11121112
# optional fractional second
1113-
fractional_second = Int64(0)
1113+
millisecond = Int64(0)
11141114
if accept(l, '.')
11151115
set_marker!(l)
11161116
found_fractional_digit = false
@@ -1121,12 +1121,15 @@ function _parse_local_time(l::Parser, skip_hour=false)::Err{NTuple{4, Int64}}
11211121
return ParserError(ErrParsingDateTime)
11221122
end
11231123
# DateTime in base only manages 3 significant digits in fractional
1124-
# second
1124+
# second. Interpret parsed digits as fractional seconds and scale to
1125+
# milliseconds precision (e.g., ".2" => 200ms, ".20" => 200ms).
1126+
ndigits = l.prevpos - l.marker
11251127
fractional_second = parse_int(l, false)::Int64
1128+
millisecond = fractional_second * 10^(3 - ndigits)
11261129
# Truncate off the rest eventual digits
11271130
accept_batch(l, isdigit)
11281131
end
1129-
return hour, minute, second, fractional_second
1132+
return hour, minute, second, millisecond
11301133
end
11311134

11321135

stdlib/TOML/test/values.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ end
116116
@test testval("2016-09-09T09:09:09Z" , DateTime(2016 , 9 , 9 , 9 , 9 , 9))
117117
@test testval("2016-09-09T09:09:09.0Z" , DateTime(2016 , 9 , 9 , 9 , 9 , 9))
118118
@test testval("2016-09-09T09:09:09.012" , DateTime(2016 , 9 , 9 , 9 , 9 , 9 , 12))
119+
@test testval("2016-09-09T09:09:09.2" , DateTime(2016 , 9 , 9 , 9 , 9 , 9 , 200))
120+
@test testval("2016-09-09T09:09:09.20" , DateTime(2016 , 9 , 9 , 9 , 9 , 9 , 200))
121+
@test testval("2016-09-09T09:09:09.02" , DateTime(2016 , 9 , 9 , 9 , 9 , 9 , 20))
119122

120123
@test failval("2016-09-09T09:09:09.0+10:00" , Internals.ErrOffsetDateNotSupported)
121124
@test failval("2016-09-09T09:09:09.012-02:00" , Internals.ErrOffsetDateNotSupported)
@@ -132,8 +135,12 @@ end
132135
end
133136

134137
@testset "Time" begin
135-
@test testval("09:09:09.99" , Time(9 , 9 , 9 , 99))
138+
@test testval("09:09:09.99" , Time(9 , 9 , 9 , 990))
136139
@test testval("09:09:09.99999" , Time(9 , 9 , 9 , 999))
140+
@test testval("00:00:00.2" , Time(0 , 0 , 0 , 200))
141+
@test testval("00:00:00.20" , Time(0 , 0 , 0 , 200))
142+
@test testval("00:00:00.23" , Time(0 , 0 , 0 , 230))
143+
@test testval("00:00:00.234" , Time(0 , 0 , 0 , 234))
137144

138145
@test failval("09:09x09", Internals.ErrParsingDateTime)
139146
end

0 commit comments

Comments
 (0)