aws / aws/aws-sdk-java-v2

DynamoDB Enhanced - DurationAttributeConverter incorrectly converts negative durations with nanosecond offsets

Open Beginner friendly
#7,060 0 comments 0 reactions 0 assignees View on GitHub
bug needs-triage
Dominant language
Java
Stars
2.6k
Forks
1k
Avg merge
2d 9h
Merged PRs (30d)
51

Description

### Describe the bug

When converting a negative `Duration` with a non-zero nanosecond offset, DynamoDB enhanced client's `DurationAttributeConverter.transformFrom` will return a value that does not match the input. Passing that returned value back into `DurationAttributeConverter.transformTo` will not return a `Duration` equal to the original value.

### Regression Issue

- [ ] Select this option if this issue appears to be a regression.

### Expected Behavior

I expect that I will receive an equivalent value after converting a negative `Duration` with a non-zero nanosecond offset to and from an `AttributeValue` with `DurationAttributeConverter`.

For example, if I create a `DurationAttributeConverter` named `converter` and call `converter.transformFrom(Duration.ofMillis(-1))`, I'd expect to receive `AttributeValue.fromN("-0.001000000")`. Subsequently calling `converter.transformTo` on that result should return `Duration.ofMillis(-1)`.

### Current Behavior

Rather than receiving an equivalent value, I received a different value `Duration.parse("PT-1.999S")` from the `transformTo` call and a value of `AttributeValue.fromN("-1.999000000")` from the `transformFrom` call.

### Reproduction Steps

```java
DurationAttributeConverter converter = DurationAttributeConverter.create();
Duration original = Duration.ofMillis(-1);
// This assertion will fail
assert original.equals(converter.transformTo(converter.transformFrom(original)));
```

### Possible Solution

The most likely reason for this bug is the internal representation used by Java for negative durations. From the `java.time.Duration.getSeconds` Javadoc:
> A negative duration is expressed by the negative sign of the seconds part. A duration of -1 nanosecond is stored as -1 seconds plus 999,999,999 nanoseconds.

### Additional Information/Context

_No response_

### AWS Java SDK version used

2.41.32

### JDK version used

openjdk 25.0.3 2026-04-21 LTS OpenJDK Runtime Environment Corretto-25.0.3.9.1 (build 25.0.3+9-LTS) OpenJDK 64-Bit Server VM Corretto-25.0.3.9.1 (build 25.0.3+9-LTS, mixed mode, sharing)

### Operating System and version

Rocky Linux release 8.10 (Green Obsidian), but will occur on any OS

Contributor guide

Open the contributing guide

Research direction

Start at DurationAttributeConverter and inspect transformFrom and transformTo, using the Duration.ofMillis(-1) reproduction from the issue. Add a regression test covering negative durations with non-zero nanosecond offsets, then run the converter's relevant tests and confirm the round trip returns the original Duration and expected AttributeValue.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
databases
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.