aws / aws/aws-sdk-java-v2

InstantAsStringAttributeConverter does not appear to have lexicographically correct sorting as claimed

Open
#2,219 3 comments 7 reactions 0 assignees View on GitHub
bug p3
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.