Skip to content

$dateToString aggregation with timezone outputs invalid ISO8601 string #1768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

NathanQingyangXu
Copy link
Contributor

@NathanQingyangXu NathanQingyangXu commented Jul 17, 2025

https://jira.mongodb.org/browse/JAVA-5044

The server upstream ticket aims to fix the following bug for the $dateToString aggregation expresison output:

  • when format is not specified and timezone is not UTC, the string should not end with Z, which would be interpreted as UTC time, not w.r.t. the specified non-UTC zone

The server bugfix will end up with removing the trailing Z from the output since v7.1.

The change is a breaking one so it was not backported to v6. From driver side, no non-testing code logic needs to be changed unless there is some tech debt as in this PR (our MqlDate#asString(TimeZone, Format) doesn't support optional format, which is a mandatory precondition of the bug reproduction).

For this reason, this PR will do the following:

  1. added a new overloaded MqlDate#asString(TimeZone) method to accommodate default format
  2. changed internal common implementation to only include format field into MQL when it was provided expecitly or through the originual MqlDate#asString(TimeZone, Format) method
  3. added new functional testing case to cover the new method; showcased that Z would be absent when non-UTC timezone is used(with server range above v7.1)

@NathanQingyangXu NathanQingyangXu requested a review from a team as a code owner July 17, 2025 18:37
@NathanQingyangXu NathanQingyangXu requested review from vbabanin and removed request for a team July 17, 2025 18:37
@NathanQingyangXu NathanQingyangXu marked this pull request as draft July 17, 2025 18:49
…egation with timezone outputs invalid ISO8601 string
@NathanQingyangXu NathanQingyangXu marked this pull request as ready for review July 17, 2025 21:58
* Ticket: JAVA-5044
*/
@Test
void dateAsStringWithDefaultFormat() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing a new API. But, since this is a bugfix, I would expect it to test an existing API, where the test would fail before the prod change, and pass afterward. Is that not the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, correct. The testing would only succeed for v7.1..0+; it would fail for v6, for instance.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not referring to the difference in test outcome based on the server version. The server would write such a test.

I mean, the ticket suggests that we need to make changes in the driver. When we write a regression test (or, all tests actually), the idea is that the test should not work before the change, but should work after. If the test works both before and after the change, the test has no relation to the change and is not testing it. If it fails both times, the change did not fix the issue.

Before the change to the production API, it is not actually possible to write a test that exhibits the bug via our API. So, no error. After the change, we can now write a test that exhibits the bug. But, we block the test from running on the server version necessary for the bug to show up. So things are "green" at first for that version, but after the prod code change, they are "red". This means we introduced a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I didn't misunderstand, you said the same testing case would fail or be red on v6, correct? That is true and I understand that is an issue.

assertExpression(
utcDateTime.withZoneSameInstant(ZoneId.of("America/New_York")).format(ISO_LOCAL_DATE_TIME),
date.asString(of("America/New_York")),
"{'$dateToString': {'date': {'$date': '2025-07-17T18:00:36.052Z'}, "
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this test value not have a Z at the end? From the Jira:

It tacks on a "Z" to the end of the string by default, which implies that it is in UTC

But here, we are expecting UTC?

Copy link
Member

@vbabanin vbabanin Jul 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Z" in the expected mql belongs to the input value, not the expected output. Expected output  comes from utcDateTime.withZoneSameInstant(ZoneId.of("America/New_York")).format(ISO_LOCAL_DATE_TIME) which is in the format of 2025‑07‑17T14:00:36.052 - this is what server returns when timezone is not UTC and format is omitted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for @vbabanin 's explanation. Yeah, the last Mql string parameter is the expected server input, not output.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks. It is the server version assume that blocks the test from running.

@@ -953,6 +953,15 @@ public MqlString asString(final MqlString timezone, final MqlString format) {
.append("timezone", toBsonValue(cr, timezone))));
}

@Override
public MqlString asString(final MqlString timezone) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that we do not need this method, and that it might actually be introducing the bug described in the Jira. That is, the API as it is now intentionally prevents the user from specifying a timezone without also forcing that user to explicitly specify a format, thus preventing the situation from arising.

For reference:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for sharing. Yeah, also saw you raising the point in our team slack channel. I have no objection of closing this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants