apps/engine 独立进程(syncRound + 防重叠调度);上游 log/token;QPU 采样; server 读 engine_status;时刻出参 toUnixSec;中文日志;zod-openapi 扩展顺序修复。
52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
/**
|
||
* 时间口径(API 响应统一 Unix 秒整数;请求 from/to 仍收 ISO 8601 便于试调)
|
||
* 库内 timestamptz ↔ JS Date ↔ Unix 秒
|
||
*/
|
||
function toDate(value: number | string | Date | null | undefined): Date | null {
|
||
if (value === null || value === undefined) return null;
|
||
let d: Date;
|
||
if (value instanceof Date) {
|
||
d = value;
|
||
} else if (typeof value === "number") {
|
||
d = new Date(value < 1e12 ? value * 1000 : value);
|
||
} else {
|
||
d = new Date(value);
|
||
}
|
||
return Number.isNaN(d.getTime()) ? null : d;
|
||
}
|
||
|
||
/** → Unix 秒(UTC);无效则 null */
|
||
export function toUnixSec(
|
||
value: number | string | Date | null | undefined,
|
||
): number | null {
|
||
const d = toDate(value);
|
||
if (!d) return null;
|
||
return Math.floor(d.getTime() / 1000);
|
||
}
|
||
|
||
/** 兼容旧名:ISO 串(仅本地/文档用;API 响应改用 toUnixSec) */
|
||
export function unixToIso(
|
||
value: number | string | Date | null | undefined,
|
||
): string | null {
|
||
const d = toDate(value);
|
||
if (!d) return null;
|
||
return d.toISOString().replace(/\.\d{3}Z$/, "Z");
|
||
}
|
||
|
||
export function isoToUnix(iso: string): number {
|
||
return Math.floor(new Date(iso).getTime() / 1000);
|
||
}
|
||
|
||
export function requireIso(value: string | null | undefined, field: string): string {
|
||
if (!value) throw new Error(`missing time field: ${field}`);
|
||
return value;
|
||
}
|
||
|
||
/** 左闭右开 [from, to) 的毫秒边界(前端传 ISO,查询用) */
|
||
export function rangeToMs(fromIso: string, toIso: string): { fromMs: number; toMs: number } {
|
||
return {
|
||
fromMs: new Date(fromIso).getTime(),
|
||
toMs: new Date(toIso).getTime(),
|
||
};
|
||
}
|