toDate accepts year strings longer than four digits and returns the wrong date

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: 8.2.4, 7.0.31, 8.2.6, 8.2.12
    • Component/s: None
    • None
    • Query Execution
    • ALL
    • Hide
      docker run -d --name repro mongo:8.2.12
      
      # wait for startup, then:
      docker exec repro mongosh --quiet test --eval '
        function t(s) {
          try { print("  " + s + "  ->  " +
            db.aggregate([{$documents: [{}]}, {$project: {_id: 0, d: {$toDate: s}}}]).toArray()[0].d.toISOString()); }
          catch (e) { print("  " + s + "  ->  error " + e.code); }
        }
        t("10000-01-01");
        t("10000-01-01T00:00:00Z");
        t("20590-01-01T00:00:00Z");
        t("20600-01-01T00:00:00Z");
      '
      
        10000-01-01  ->  2000-01-01T09:59:50.000Z
        10000-01-01T00:00:00Z  ->  error 241
        20590-01-01T00:00:00Z  ->  error 241
        20600-01-01T00:00:00Z  ->  2000-01-01T00:00:00.000Z
      
      Show
      docker run -d --name repro mongo:8.2.12 # wait for startup, then: docker exec repro mongosh --quiet test --eval ' function t(s) { try { print(" " + s + " -> " + db.aggregate([{$documents: [{}]}, {$project: {_id: 0, d: {$toDate: s}}}]).toArray()[0].d.toISOString()); } catch (e) { print(" " + s + " -> error " + e.code); } } t("10000-01-01"); t("10000-01-01T00:00:00Z"); t("20590-01-01T00:00:00Z"); t("20600-01-01T00:00:00Z"); ' 10000-01-01 -> 2000-01-01T09:59:50.000Z 10000-01-01T00:00:00Z -> error 241 20590-01-01T00:00:00Z -> error 241 20600-01-01T00:00:00Z -> 2000-01-01T00:00:00.000Z
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      A date string with a five digit year is accepted and comes back as an unrelated date. "10000-01-01" returns 2000-01-01T09:59:50Z. The year is wrong and there is a time on it that was not in the input.

      The same year with an explicit time part is rejected with error 241, so the two forms disagree about whether the input is valid.

      Of the strings that do have a time part, which ones are accepted does not follow the size of the year. "20590-01-01T00:00:00Z" is rejected and "20600-01-01T00:00:00Z" is accepted. The accepted ones return a year built from the trailing digits.

      Input Returned
      19990-01-01T00:00:00Z 2000-01-01
      199990-01-01T00:00:00Z 1990-01-01
      999999-01-01T00:00:00Z 1999-01-01
      300069-01-01T00:00:00Z 2069-01-01

      $convert with to: "date" behaves the same way.

      No error is surfaced, so a document with a malformed year is stored with a plausible looking date.

      Expected

      Error 241 ConversionFailure for any year longer than four digits, which is what "10000-01-01T00:00:00Z" already returns.

      Actual

      The string is accepted and a different date comes back, with nothing logged.

            Assignee:
            Unassigned
            Reporter:
            Daniel Frankcom (EXT)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: