Neo4j DateTime Zone ID Persistence and Local Conversion Limits
0 reputation · 21 Aug 2023, 10:11 UTC
0 reputation · 21 Aug 2023, 10:11 UTC
Neo4j implements the ISO 8601 standard for temporal data, allowing DateTime objects to store specific timezone identifiers or offsets. This capability is essential for maintaining regional context across distributed datasets.
A design challenge arises when converting these zoned representations into LocalDateTime for regional reporting. Because LocalDateTime is timezone-unaware by design, the conversion process effectively strips the zone ID, potentially creating ambiguity when the same wall-clock time exists across multiple regional offsets.
Given these constraints, what is the expected behavior when comparing a DateTime with a specific zone ID against a LocalDateTime value? Does the engine perform an implicit conversion to the system's local time, or does it treat the comparison as a literal value match regardless of the original zone?
In Neo4j, a DateTime always stores an instant in UTC together with the original zone ID or offset. A LocalDateTime has no zone information – it’s just a wall‑clock moment. When Cypher evaluates a comparison such as $dt = $ldt, Neo4j performs an implicit coercion of the LocalDateTime into a DateTime by applying the server’s default time zone (configured in neo4j.conf via dbms.timezone).
After coercion, the comparison is carried out on the two resulting UTC instants. The original zone ID of the DateTime is preserved during this process; it is not ignored or replaced by the local zone. Therefore:
LocalDateTime represents the same instant as the DateTime when interpreted in the server’s default zone, the comparison returns true.falsedbms.timezone=UTC.
# neo4j.conf
dbms.timezone=UTC
DateTime with a non‑UTC zone ID:
WITH datetime({ year:2026, month:10, day:10, hour:21, minute:13, second:25, zoneId:'America/New_York' }) AS dt
RETURN dt;
LocalDateTime for the same wall‑clock time:
WITH localdatetime({ year:2026, month:10, day:10, hour:21, minute:13, second:25 }) AS ldt
RETURN ldt;
RETURN $dt = $ldt;
UTC as the server zone, the comparison will be false because 21:13:25 in New York is 01:13:25 UTC the next day. Changing the server zone to America/New_York would make the comparison return true.DateTime when comparing to a LocalDateTime.
dbms.timezone to the zone you intend to use for comparisons, or explicitly convert the LocalDateTime to the desired zone using datetime({… zoneId:… }) before comparing.If you’re unsure what the server’s default time zone is in your deployment, run:
RETURN apoc.meta.getConfig('dbms.timezone');
This will reveal the current zone and help determine whether your comparison logic needs adjustment.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.