Repository navigation
Temporal map constructors reject microsecond values 1000–999999, contrary to openCypher TCK #5096
Description
Memgraph version
- Memgraph 3.13.2
- Also reproduced on Memgraph 3.12.0 and 3.11.0
- Reference: Neo4j 2026.05.0-community (behaves as expected)
Description
Memgraph rejects valid microsecond values greater than 999 when constructing temporal values from Cypher maps.
According to the openCypher TCK (Temporal1.feature, scenarios [5] and [8]), a standalone microsecond component may represent the full microsecond-of-second range (0–999999).
For example, microsecond: 645876 should produce a fractional second of .645876.
Memgraph instead raises an exception for any microsecond value greater than 999.
This affects localtime() and datetime() map constructors.
Steps to reproduce
Run:
RETURN localtime({
hour: 12,
minute: 31,
second: 14,
microsecond: 645876
}) AS t;Expected result (openCypher TCK):
12:31:14.645876
Actual result (Memgraph 3.13.2):
Memgraph.TransientError.MemgraphError
Creating a LocalTime with invalid microseconds parameter.
Neo4j 2026.05.0-community accepts the same query and returns the expected value.
Boundary tests
The following values were tested on Memgraph 3.13.2:
microsecond |
Memgraph 3.13.2 | Expected behavior |
|---|---|---|
| 0 | Accepted | Accepted |
| 999 | Accepted | Accepted |
| 1000 | Error: invalid microseconds parameter | Accepted (.001000) |
| 645876 | Error: invalid microseconds parameter | Accepted (.645876) |
| 999999 | Error: invalid microseconds parameter | Accepted (.999999) |
Values from 0 through 999 are accepted, but values beginning at 1000 are incorrectly rejected.
The same range limitation was observed with datetime().
For example:
RETURN datetime({
year: 1984,
month: 10,
day: 11,
hour: 12,
minute: 31,
second: 14,
microsecond: 645876,
timezone: '+01:00'
}) AS dt;Expected:
1984-10-11T12:31:14.645876+01:00
Memgraph rejects the microsecond parameter instead.
openCypher TCK reference
The expected behavior is explicitly covered by the official openCypher Technology Compatibility Kit:
Source:
Scenario [5], "Should construct local time", contains:
{hour: 12, minute: 31, second: 14, microsecond: 645876}
-> '12:31:14.645876'
Scenario [8], "Should construct date time with default time zone", likewise expects:
{year: 1984, month: 10, day: 11,
hour: 12, minute: 31, second: 14,
microsecond: 645876}
-> '1984-10-11T12:31:14.645876Z'
The TCK also distinguishes standalone microsecond-of-second values from combinations of subsecond components.
For example:
RETURN localtime({
hour: 12,
minute: 31,
second: 14,
millisecond: 123,
microsecond: 456,
nanosecond: 789
});The TCK expects:
12:31:14.123456789
Thus, microsecond: 645876 without a separate millisecond component is valid and must not be rejected merely because it exceeds 999.
Possible root cause
The Memgraph 3.13.2 implementation appears to validate the internal microsecond remainder directly against a range of 0–999.
In src/utils/temporal.cpp:
if (!IsInBounds(0, 999, local_time_parameters.microsecond)) {
throw temporal::InvalidArgumentException(
"Creating a LocalTime with invalid microseconds parameter.");
}Source:
https://github.com/memgraph/memgraph/blob/v3.13.2/src/utils/temporal.cpp#L395-L413
The Cypher localtime() map constructor passes the supplied value directly into this internal parameter:
std::pair{"microsecond"sv, &local_time_parameters.microsecond},Source:
The internal representation separates milliseconds and microseconds, which explains the 0–999 remainder check. However, a standalone Cypher map component representing 645876 microseconds should be interpreted as 645 milliseconds plus 876 additional microseconds.
The constructor appears to reject such values before performing the required normalization.
A fix may therefore require adjusting map-component normalization rather than simply increasing the internal field's validation limit.
Impact
- Valid openCypher temporal map expressions fail at runtime.
- Applications constructing timestamps from microsecond-of-second values cannot use the complete valid range.
- Queries using
localtime()anddatetime()behave differently from openCypher TCK expectations and Neo4j. - The failure affects values starting at 1000 microseconds, not only extreme or out-of-range inputs.
Expected behavior
Memgraph should accept standalone microsecond values in the range 0–999999 and construct the corresponding temporal value, consistent with openCypher TCK Temporal1 scenarios [5] and [8].
For example:
RETURN localtime({
hour: 12,
minute: 31,
second: 14,
microsecond: 645876
}) AS t;should return:
12:31:14.645876
instead of raising an invalid microseconds parameter error.
Activity