InstantAsStringAttributeConverter does not appear to have lexicographically correct sorting as claimed
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 51
Description
## Describe the bug
InstantAsStringAttributeConverter claims that its provided serialization is lexicographically sortable given that the year of the Instant is non-negative. It seems to also not be lexicographically sortable if any value falls directly on a second, since InstantAsStringAttributeConverter simply calls `toString()`, which uses an adapting ISO 8601 formatter that will truncate 3-groups of zero values:
From Instant's toString():
> The format used is the same as DateTimeFormatter.ISO_INSTANT.
From DateTimeFormatter's [ISO_INSTANT](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#ISO_INSTANT):
> The nano-of-second outputs zero, three, six or nine digits as necessary.
The manifestation of this problem was a query on a sort key that, when re-sorted in application code, changed its order.
## Expected Behavior
When using an Instant as a sort key on a DynamoDbBean, I expect sort orderings like this to be returned by a query:
```
2020-12-23T07:05:28.991Z
2020-12-23T07:05:29Z
2020-12-23T07:05:29.017Z
```
## Current Behavior
Instead I'm getting orderings like this:
```
2020-12-23T07:05:28.991Z
2020-12-23T07:05:29.017Z
2020-12-23T07:05:29Z
```
since `Z` comes after `.` lexicographically. This disagrees with the natural sort order of the corresponding Instants.
## Steps to Reproduce
Create a Dynamo schema with a string sort key, write two instants that share a second, but ensure one of them falls directly on the second while the other has some fractional component.
## Possible Solution
Use `new DateTimeFormatterBuilder().appendInstant(9).toFormatter()` to control the number of zeros. For any values taken from `System.currentTimeMillis()` there will be a lot of unnecessary zeros, but I don't think there's any other correct default behavior.
## Context
It's nice to combine the enhanced client's ability to use native Java types with querying by time. In this case the workaround is pretty straightforward for my case.
## Your Environment
* AWS Java SDK version used: 2.15.50
* JDK version used: 11
* Operating System and version: Mac OS X 10.15.7
Contributor guide
Assessment
This issue has not been assessed yet.