mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 08:09:27 +00:00
fix(ui): accept hour-only offsets when pasting a date-time (#15495)
Co-authored-by: Abhay Padamani <141122205+ktx-abhay@users.noreply.github.com>
This commit is contained in:
co-authored by
Abhay Padamani
parent
addf3e4df5
commit
e816c0974e
@@ -78,6 +78,15 @@ describe("parseDateRangeString", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts an hour-only offset (+HH), which date-fns renders for whole-hour zones", () => {
|
||||
// 08:33:06-05 is the same instant as 13:33:06Z.
|
||||
expect(parseDateRangeString("2026-07-21T08:33:06-05 - 2026-07-21T10:33:06-05")).toEqual({
|
||||
type: "timestamp",
|
||||
startMicros: 1784640786000000,
|
||||
endMicros: 1784647986000000,
|
||||
});
|
||||
});
|
||||
|
||||
it("without an offset, resolves to the picker-timezone-dependent absolute shape", () => {
|
||||
expect(parseDateRangeString("2026-07-21T13:33:06 - 2026-07-21T15:33:06")).toEqual({
|
||||
type: "absolute",
|
||||
@@ -399,6 +408,17 @@ describe("parseSingleDateTime", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("with an hour-only offset, as formatToHuman renders it in a whole-hour zone", () => {
|
||||
expect(parseSingleDateTime("Jul 22, 2026 01:40:28.008 -05")).toEqual({
|
||||
type: "timestamp",
|
||||
micros: 1784702428008000,
|
||||
});
|
||||
expect(parseSingleDateTime("Jul 22, 2026 08:40:28.008 +02")).toEqual({
|
||||
type: "timestamp",
|
||||
micros: 1784702428008000,
|
||||
});
|
||||
});
|
||||
|
||||
it("without milliseconds", () => {
|
||||
expect(parseSingleDateTime("Jul 22, 2026 06:40:28 +0000")).toEqual({
|
||||
type: "timestamp",
|
||||
|
||||
@@ -55,10 +55,10 @@ const TIMESTAMP_RANGE_RE = /^(\d{10,16})\s*-\s*(\d{10,16})$/;
|
||||
const ABSOLUTE_SINGLE_RE = /^(\d{4}\/\d{2}\/\d{2})(?:\s+(\d{2}:\d{2}:\d{2}))?$/;
|
||||
const TIMESTAMP_SINGLE_RE = /^(\d{10,16})$/;
|
||||
const ISO_SINGLE_RE =
|
||||
/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?(Z|[+-]\d{2}:?\d{2})?$/;
|
||||
/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?)?(Z|[+-]\d{2}(?::?\d{2})?)?$/;
|
||||
// The app's own log/trace timestamp display format (src/utils/date.ts formatTimestamp).
|
||||
const HUMAN_LOG_SINGLE_RE =
|
||||
/^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{1,2}),?\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(?:\s+(Z|[+-]\d{2}:?\d{2}))?$/i;
|
||||
/^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{1,2}),?\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,3}))?(?:\s+(Z|[+-]\d{2}(?::?\d{2})?))?$/i;
|
||||
const MONTH_INDEX: Record<string, string> = {
|
||||
jan: "01",
|
||||
feb: "02",
|
||||
@@ -74,6 +74,13 @@ const MONTH_INDEX: Record<string, string> = {
|
||||
dec: "12",
|
||||
};
|
||||
|
||||
// date-fns `X` (the app's `Z` token) renders whole-hour zones as `+HH`, with no minutes.
|
||||
function normalizeOffset(offset: string): string {
|
||||
if (offset.toUpperCase() === "Z") return "Z";
|
||||
const [, hours, minutes = "00"] = offset.match(/^([+-]\d{2}):?(\d{2})?$/) ?? [];
|
||||
return `${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
function isValidDateTimeParts(
|
||||
year: string,
|
||||
month: string,
|
||||
@@ -208,8 +215,7 @@ function parseIsoSingle(raw: string): IsoSingleParsed | null {
|
||||
|
||||
if (offset) {
|
||||
// Explicit offset already IS the instant — ignores the picker's timezone.
|
||||
const normalizedOffset =
|
||||
offset === "Z" ? "Z" : offset.replace(/^([+-]\d{2}):?(\d{2})$/, "$1:$2");
|
||||
const normalizedOffset = normalizeOffset(offset);
|
||||
const iso = `${year}-${month}-${day}T${hour ?? "00"}:${minute ?? "00"}:${second ?? "00"}${normalizedOffset}`;
|
||||
const ms = Date.parse(iso);
|
||||
if (Number.isNaN(ms)) return null;
|
||||
@@ -234,8 +240,7 @@ function parseHumanLogSingle(raw: string): IsoSingleParsed | null {
|
||||
if (!isValidDateTimeParts(year, month, dd, hour, minute, secWithMs)) return null;
|
||||
|
||||
if (offset) {
|
||||
const normalizedOffset =
|
||||
offset.toUpperCase() === "Z" ? "Z" : offset.replace(/^([+-]\d{2}):?(\d{2})$/, "$1:$2");
|
||||
const normalizedOffset = normalizeOffset(offset);
|
||||
const iso = `${year}-${month}-${dd}T${hour}:${minute}:${secWithMs}${normalizedOffset}`;
|
||||
const parsedMs = Date.parse(iso);
|
||||
if (Number.isNaN(parsedMs)) return null;
|
||||
|
||||
Reference in New Issue
Block a user