diff --git a/ruby/ext/google/protobuf_c/message.c b/ruby/ext/google/protobuf_c/message.c index f8661dfb2b4bd..259f5e666d689 100644 --- a/ruby/ext/google/protobuf_c/message.c +++ b/ruby/ext/google/protobuf_c/message.c @@ -1287,7 +1287,7 @@ const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m, if (!rb_obj_is_kind_of(value, rb_cNumeric)) goto badtype; sec.int64_val = NUM2LL(value); - nsec.int32_val = (NUM2DBL(value) - NUM2LL(value)) * 1000000000; + nsec.int32_val = round((NUM2DBL(value) - NUM2LL(value)) * 1000000000); upb_msg_set(msg, sec_f, sec, arena); upb_msg_set(msg, nsec_f, nsec, arena); return msg; diff --git a/ruby/tests/common_tests.rb b/ruby/tests/common_tests.rb index 589934b0e92f6..1957422fa9374 100644 --- a/ruby/tests/common_tests.rb +++ b/ruby/tests/common_tests.rb @@ -1701,6 +1701,12 @@ def test_converts_duration m = proto_module::TimeMessage.new(duration: 1.1) assert_equal Google::Protobuf::Duration.new(seconds: 1, nanos: 100_000_000), m.duration + m = proto_module::TimeMessage.new(duration: 123.321) + assert_equal Google::Protobuf::Duration.new(seconds: 123, nanos: 321_000_000), m.duration + + m = proto_module::TimeMessage.new(duration: -123.321) + assert_equal Google::Protobuf::Duration.new(seconds: -123, nanos: -321_000_000), m.duration + assert_raise(Google::Protobuf::TypeError) { m.duration = '2' } assert_raise(Google::Protobuf::TypeError) { m.duration = proto_module::TimeMessage.new } end