Add computeTransferMinutes and formatMinutesAsDuration helpers
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { computeTransferMinutes, formatMinutesAsDuration } from "./computeTransferTime.js";
|
||||
|
||||
describe("computeTransferMinutes", () => {
|
||||
it("returns positive diff in minutes", () => {
|
||||
expect(computeTransferMinutes("2026-04-17T10:00:00Z", "2026-04-17T11:30:00Z")).toBe(90);
|
||||
});
|
||||
|
||||
it("returns 0 when times are identical", () => {
|
||||
const t = "2026-04-17T10:00:00Z";
|
||||
expect(computeTransferMinutes(t, t)).toBe(0);
|
||||
});
|
||||
|
||||
it("returns null when departure is before arrival (negative)", () => {
|
||||
expect(computeTransferMinutes("2026-04-17T11:00:00Z", "2026-04-17T10:00:00Z")).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when arrival is undefined", () => {
|
||||
expect(computeTransferMinutes(undefined, "2026-04-17T10:00:00Z")).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when departure is undefined", () => {
|
||||
expect(computeTransferMinutes("2026-04-17T10:00:00Z", undefined)).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null for invalid ISO strings", () => {
|
||||
expect(computeTransferMinutes("not-a-date", "2026-04-17T10:00:00Z")).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("formatMinutesAsDuration", () => {
|
||||
it("formats 90 minutes as '1h 30m'", () => {
|
||||
expect(formatMinutesAsDuration(90)).toBe("1h 30m");
|
||||
});
|
||||
|
||||
it("formats 45 minutes as '45m'", () => {
|
||||
expect(formatMinutesAsDuration(45)).toBe("45m");
|
||||
});
|
||||
|
||||
it("formats 60 minutes as '1h'", () => {
|
||||
expect(formatMinutesAsDuration(60)).toBe("1h");
|
||||
});
|
||||
|
||||
it("formats 0 as '0m'", () => {
|
||||
expect(formatMinutesAsDuration(0)).toBe("0m");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { parseISO, differenceInMinutes, isValid } from "date-fns";
|
||||
|
||||
/**
|
||||
* Diff (in minutes) between departure and arrival ISO UTC strings.
|
||||
* Returns null when either input is missing/invalid, or when result is negative.
|
||||
*/
|
||||
export function computeTransferMinutes(
|
||||
arrivalUtc: string | undefined,
|
||||
departureUtc: string | undefined,
|
||||
): number | null {
|
||||
if (!arrivalUtc || !departureUtc) return null;
|
||||
const arr = parseISO(arrivalUtc);
|
||||
const dep = parseISO(departureUtc);
|
||||
if (!isValid(arr) || !isValid(dep)) return null;
|
||||
const diff = differenceInMinutes(dep, arr);
|
||||
if (diff < 0) return null;
|
||||
return diff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a minute count as "Nh Mm" (or "Mm" when <1 hour, or "Nh" when no remainder).
|
||||
*/
|
||||
export function formatMinutesAsDuration(minutes: number): string {
|
||||
if (minutes < 60) return `${minutes}m`;
|
||||
const h = Math.floor(minutes / 60);
|
||||
const m = minutes % 60;
|
||||
if (m === 0) return `${h}h`;
|
||||
return `${h}h ${m}m`;
|
||||
}
|
||||
Reference in New Issue
Block a user