You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by jl...@apache.org on 2026/09/16 00:33:36 UTC
(superset) 01/01: fix(time-format): stop reading short digit-only strings as epoch offsets
This is an automated email from the ASF dual-hosted git repository.
sadpandajoe pushed a commit to branch ultraset-fix-43847
in repository https://gitbox.apache.org/repos/asf/superset.git
commit f390d7e6f000a8c7262d9fe25d6f28f4c7581ee1
Author: sadpandajoe <sa...@users.noreply.github.com>
AuthorDate: Wed Sep 16 00:32:04 2026 +0000
fix(time-format): stop reading short digit-only strings as epoch offsets
stringifyTimeInput() only carved out the four-digit ISO year form
(#43909); any other digit-only string, including a bare YYYYMMDD date
key like "20260903", was still read as epoch milliseconds and rendered
as 1970. Require at least 10 digits before treating a string as a
plausible epoch timestamp; anything shorter that isn't a four-digit
year now falls through to Date parsing and the existing NaN fallback,
which returns the original value unchanged instead of a wrong date.
Fixes #43847
Co-Authored-By: Claude Sonnet 5 <no...@anthropic.com>
---
.../src/time-format/utils/stringifyTimeInput.ts | 15 ++++++++++-----
.../test/time-format/utils/stringifyTimeInput.test.ts | 16 ++++++++++++++++
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/utils/stringifyTimeInput.ts b/superset-frontend/packages/superset-ui-core/src/time-format/utils/stringifyTimeInput.ts
index 1573d193ab6..6d336705b9e 100644
--- a/superset-frontend/packages/superset-ui-core/src/time-format/utils/stringifyTimeInput.ts
+++ b/superset-frontend/packages/superset-ui-core/src/time-format/utils/stringifyTimeInput.ts
@@ -29,15 +29,20 @@ export default function stringifyTimeInput(
if (typeof value === 'string') {
const trimmed = value.trim();
// A bare four-digit string is the ISO 8601 year-only form ("2017"), which
- // every engine parses as January 1st of that year. Any other integer
- // string is an epoch timestamp in milliseconds that was stringified on
- // its way here, e.g. by the pivot table, and is not a valid Date input.
+ // every engine parses as January 1st of that year. A digit-only string
+ // of at least 10 digits is long enough to plausibly be an epoch
+ // timestamp in milliseconds that was stringified on its way here, e.g.
+ // by the pivot table. Anything shorter that isn't a four-digit year -
+ // a YYYYMMDD date key such as "20260903", for instance - is neither, so
+ // it is handed to `new Date(value)` like any other string; that resolves
+ // to an Invalid Date and falls back to the original input below instead
+ // of being silently misread as a moment near 1970.
const isYear = /^\d{4}$/.test(trimmed);
- const isIntegerString = /^-?\d+$/.test(trimmed);
+ const isPlausibleEpoch = /^-?\d{10,}$/.test(trimmed);
if (isYear) {
time = new Date(trimmed);
} else {
- time = new Date(isIntegerString ? Number(trimmed) : value);
+ time = new Date(isPlausibleEpoch ? Number(trimmed) : value);
}
} else {
time = value instanceof Date ? value : new Date(value);
diff --git a/superset-frontend/packages/superset-ui-core/test/time-format/utils/stringifyTimeInput.test.ts b/superset-frontend/packages/superset-ui-core/test/time-format/utils/stringifyTimeInput.test.ts
index 9fd9b8d68ce..73658596301 100644
--- a/superset-frontend/packages/superset-ui-core/test/time-format/utils/stringifyTimeInput.test.ts
+++ b/superset-frontend/packages/superset-ui-core/test/time-format/utils/stringifyTimeInput.test.ts
@@ -69,6 +69,22 @@ test('treats a four-digit integer string as a year, not as milliseconds', () =>
);
});
+test('does not treat a short non-year digit-only string as epoch milliseconds', () => {
+ // A YYYYMMDD date key or bare year-adjacent string like these is neither
+ // the four-digit year form nor long enough to plausibly be an epoch
+ // timestamp, so it must be left unchanged rather than silently rendered
+ // as a moment near 1970.
+ expect(stringifyTimeInput('20260903', format)).toBe('20260903');
+ expect(stringifyTimeInput('19870214', format)).toBe('19870214');
+ expect(stringifyTimeInput('999999999', format)).toBe('999999999');
+});
+
+test('treats a ten-digit integer string as epoch milliseconds', () => {
+ expect(stringifyTimeInput('1000000000', format)).toBe(
+ '1970-01-12T13:46:40.000Z',
+ );
+});
+
test('returns the original input of an unparseable DateWithFormatter without re-entering the formatter', () => {
// The `${value}` fallback calls `DateWithFormatter.toString()`, which must
// return the input rather than call the formatter again, or the two would