diff --git a/lib/fluent/time.rb b/lib/fluent/time.rb index e535a027ab..58b8b71677 100644 --- a/lib/fluent/time.rb +++ b/lib/fluent/time.rb @@ -346,7 +346,7 @@ def parse_float(value) begin sec_s, nsec_s, _ = value.to_s.split('.', 3) # throw away second-dot and later - nsec_s = nsec_s && nsec_s[0..9] || '0' + nsec_s = nsec_s && nsec_s[0, 9] || '0' # nanoseconds: 9 digits at most nsec_s += '0' * (9 - nsec_s.size) if nsec_s.size < 9 time = Fluent::EventTime.new(sec_s.to_i, nsec_s.to_i) rescue => e diff --git a/test/test_time_parser.rb b/test/test_time_parser.rb index 7575a2e24d..6c4ac1a19e 100644 --- a/test/test_time_parser.rb +++ b/test/test_time_parser.rb @@ -359,4 +359,21 @@ class DummyForTimeParser assert_equal([expected, expected + 1], [time1, time2]) end + + # A float timestamp's fraction is nanoseconds: at most 9 digits, and always below + # 1_000_000_000 like every other EventTime producer. + def test_parse_float_keeps_nine_digits_of_the_fraction + parser = Fluent::NumericTimeParser.new(:float) + + assert_equal_event_time(Fluent::EventTime.new(1700000000, 123456789), parser.parse('1700000000.123456789')) + assert_equal_event_time(Fluent::EventTime.new(1700000000, 123456789), parser.parse('1700000000.1234567890')) + assert_equal_event_time(Fluent::EventTime.new(1700000000, 999999999), parser.parse('1700000000.9999999999')) + assert_equal_event_time(Fluent::EventTime.new(0, 0), parser.parse('0.0000000001')) + + (1..20).each do |n| + time = parser.parse("1700000000.#{'9' * n}") + assert_true time.nsec < 1_000_000_000, "nsec #{time.nsec} is out of range with #{n} digits of fraction" + end + end + end