Skip to content

Commit b56ab3f

Browse files
committed
Improve date parsing from search query
1 parent b984631 commit b56ab3f

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

apps/webapp/app/routes/api.v1.deployments.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export const loader = createLoaderApiRoute(
126126
);
127127

128128
import parseDuration from "parse-duration";
129+
import { parseDate } from "@trigger.dev/core/v3/isomorphic";
129130

130131
function getCreatedAtFilter(searchParams: ApiDeploymentListSearchParams) {
131132
if (searchParams.period) {
@@ -171,8 +172,9 @@ function getCreatedAtFilter(searchParams: ApiDeploymentListSearchParams) {
171172
}
172173

173174
function safeDateFromString(value: string, paramName: string) {
174-
const date = new Date(value);
175-
if (isNaN(date.getTime())) {
175+
const date = parseDate(value);
176+
177+
if (!date) {
176178
throw new ServiceValidationError(`Invalid search query parameter: ${paramName}=${value}`, 400);
177179
}
178180
return date;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Attempts to parse a string into a valid Date.
3+
*
4+
* Supported formats:
5+
* - ISO and RFC date strings (e.g. "2025-08-18", "2025-08-18T12:34:56Z")
6+
* - Natural language dates supported by JS Date (e.g. "August 18, 2025")
7+
* - Epoch seconds (10-digit numeric string, e.g. "1629302400")
8+
* - Epoch milliseconds (13-digit numeric string, e.g. "1629302400000")
9+
*
10+
* @param input The string to parse.
11+
* @returns A valid Date object, or undefined if parsing fails.
12+
*/
13+
export function parseDate(input: string): Date | undefined {
14+
if (typeof input !== "string") return undefined;
15+
16+
// Handle pure numeric strings as epoch values
17+
if (/^\d+$/.test(input)) {
18+
const num = Number(input);
19+
20+
if (input.length === 10) {
21+
// Epoch seconds
22+
return new Date(num * 1000);
23+
} else if (input.length === 13) {
24+
// Epoch milliseconds
25+
return new Date(num);
26+
} else {
27+
// Unsupported numeric length
28+
return undefined;
29+
}
30+
}
31+
32+
// Handle general date strings
33+
const date = new Date(input);
34+
return isNaN(date.getTime()) ? undefined : date;
35+
}

packages/core/src/v3/isomorphic/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from "./maxDuration.js";
44
export * from "./queueName.js";
55
export * from "./consts.js";
66
export * from "./traceContext.js";
7+
export * from "./dates.js";

0 commit comments

Comments
 (0)