-
Notifications
You must be signed in to change notification settings - Fork 964
Description
Describe the bug
When unmarshalling specific timestamp values from responses which utilize a JSON-based protocol that serializes the values as UNIX_TIMESTAMP (seconds with fractional millisecond values), the value unmarshalled will sometimes be off by 1 millisecond.
Regression Issue
- Select this option if this issue appears to be a regression.
Expected Behavior
A response with a timestamp value of 1099510880.771 is unmarshalled as the Instant value 2004-11-03T19:41:20.771Z
Current Behavior
A response with a timestamp value of 1099510880.771 is unmarshalled as the Instant value 2004-11-03T19:41:20.770Z
Reproduction Steps
I don't have library usage reproduction steps, but the issue becomes obvious when performing the same operations as the suspected code:
Instant.ofEpochMilli((long) (value.doubleValue() * 1_000d));
$ jshell
| Welcome to JShell -- Version 21.0.5
| For an introduction type: /help intro
jshell> import java.time.Instant;
jshell> Instant.ofEpochMilli((long) (1099510880.771d * 1_000d));
$2 ==> 2004-11-03T19:41:20.770Z
This is caused by the result of 1099510880.771d * 1_000d having IEEE 754 double precision multiplication issues:
jshell> 1099510880.771d * 1_000d;
$3 ==> 1.0995108807709999E12
Possible Solution
Instead of simply casting the resulting double to long, use Math.round(double) to get the correctly rounded value.
I've identified two places that this incorrect logic is used:
- NumberToInstant -
Line 54 in f19cff6
return Instant.ofEpochMilli((long) (value.doubleValue() * 1_000d)); - JsonUnmarshallingParser -
Line 388 in f19cff6
return Instant.ofEpochMilli((long) (parser.getDoubleValue() * 1_000d));
Additional Information/Context
I haven't done a deep check into how prevalent this rounding issue specifically causes off-by-one timestamps, a quick script found that dates between 2004 and 2025 don't appear to be impacted; however there's plenty of dates which are impacted before 2004.
I'm working on a pull request with the possible solution above. Feel free to contact me on slack at bnd@ if needed.
AWS Java SDK version used
2.31.30
JDK version used
openjdk version "21.0.5" 2024-10-15 LTS / OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS) / OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)
Operating System and version
Mac Sequoia 15.3.2