import { describe, expect, it } from "@effect/vitest"; import { compareDateTimeStrings } from "./dateTime.ts"; describe("compareDateTimeStrings", () => { it("compares valid date-time strings by absolute time", () => { expect( compareDateTimeStrings("2026-09-01T12:00:00.000Z", "2026-09-01T05:00:00.000-07:00"), ).toBe(0); expect( compareDateTimeStrings("2026-09-01T12:00:01.000Z", "2026-09-01T12:00:00.000Z"), ).toBeGreaterThan(0); }); it.each([ ["2024-02-29T12:00:00Z", "2024-02-29T17:30:00+05:30"], ["2000-02-29T00:00:00.100Z", "2000-02-28T20:30:00.1-03:30"], ["0000-01-01T00:00:00.000Z", "+000000-01-01T00:00:00.000+00:00"], ["+010000-01-01T00:00:00.000Z", "9999-12-31T23:00:00.000-01:00"], ["2026-09-01T24:00:00Z", "2026-09-02T00:00:00Z"], ["2026-09-01T24:00:00.0000Z", "2026-09-02T00:00:00.000Z"], ["2024-02-29T24:00:00+05:30", "2024-03-01T00:00:00+05:30"], ["2026-12-31T24:00:00-07:00", "2027-01-01T07:00:00Z"], ["2026-09-01T12:00Z", "2026-09-01T12:00:00.000Z"], ["2026-09-01T05:00-07:00", "2026-09-01T12:00:00Z"], ["2026-09-01T24:00Z", "2026-09-02T00:00:00Z"], ["2026-09-01T24:00+05:30", "2026-09-02T00:00:00+05:30"], ])("preserves equal ISO instants %s and %s", (left, right) => { expect(compareDateTimeStrings(left, right)).toBe(0); }); it("sorts malformed values before valid values", () => { expect(compareDateTimeStrings("invalid", "2026-09-01T12:00:00.000Z")).toBeLessThan(0); expect(compareDateTimeStrings("2026-09-01T12:00:00.000Z", "invalid")).toBeGreaterThan(0); }); it.each([ "2014-02-30", "2014-03-02", "2014-03-02T00:00:00", "2014-03-02T00:00:00.000", "03/02/2014", "March 2, 2014", "Sun, 02 Mar 2014 00:00:00 GMT", "2014-03-02T00:00:00.000Z\n", "2014-02-30T00:00:00.000Z", "1900-02-29T00:00:00.000-07:00", "2024-04-31T00:00:00.000+05:30", "2024-03-02T12:00:00.000+24:00", "2026-09-01T24:01:00Z", "2026-09-01T24:00:01Z", "2026-09-01T24:00:00.0001Z", "2026-09-01T24:01Z", "2026-09-01T25:00Z", ])("treats %s as malformed without native date guessing", (malformed) => { const valid = "1970-01-01T00:00:00.000Z"; expect(compareDateTimeStrings(malformed, valid)).toBeLessThan(0); expect(compareDateTimeStrings(valid, malformed)).toBeGreaterThan(0); expect(compareDateTimeStrings(malformed, "invalid")).toBeLessThan(0); expect(compareDateTimeStrings("invalid", malformed)).toBeGreaterThan(0); expect(compareDateTimeStrings(malformed, malformed)).toBe(0); }); it("uses code-unit order for malformed date-time strings", () => { expect(compareDateTimeStrings("invalid-a", "invalid-B")).toBeGreaterThan(0); expect(compareDateTimeStrings("invalid-B", "invalid-a")).toBeLessThan(0); }); it("returns zero for equal malformed date-time strings", () => { expect(compareDateTimeStrings("invalid", "invalid")).toBe(0); }); it("gives every permutation of mixed values the same order", () => { const early = "2026-09-01T12:00:00.000+14:00"; const late = "2026-09-01T00:00:00.000-12:00"; const malformed = "2026-09-01T06:invalid"; const expected = [malformed, early, late]; const permutations = [ [early, late, malformed], [early, malformed, late], [late, early, malformed], [late, malformed, early], [malformed, early, late], [malformed, late, early], ]; for (const values of permutations) { expect(values.toSorted(compareDateTimeStrings)).toEqual(expected); } });});
import { describe, expect, it } from "@effect/vitest";
import { compareDateTimeStrings } from "./dateTime.ts";
describe("compareDateTimeStrings", () => {
it("compares valid date-time strings by absolute time", () => {
expect(
compareDateTimeStrings("2026-09-01T12:00:00.000Z", "2026-09-01T05:00:00.000-07:00"),
).toBe(0);
expect(
compareDateTimeStrings("2026-09-01T12:00:01.000Z", "2026-09-01T12:00:00.000Z"),
).toBeGreaterThan(0);
});
it.each([
["2024-02-29T12:00:00Z", "2024-02-29T17:30:00+05:30"],
["2000-02-29T00:00:00.100Z", "2000-02-28T20:30:00.1-03:30"],
["0000-01-01T00:00:00.000Z", "+000000-01-01T00:00:00.000+00:00"],
["+010000-01-01T00:00:00.000Z", "9999-12-31T23:00:00.000-01:00"],
["2026-09-01T24:00:00Z", "2026-09-02T00:00:00Z"],
["2026-09-01T24:00:00.0000Z", "2026-09-02T00:00:00.000Z"],
["2024-02-29T24:00:00+05:30", "2024-03-01T00:00:00+05:30"],
["2026-12-31T24:00:00-07:00", "2027-01-01T07:00:00Z"],
["2026-09-01T12:00Z", "2026-09-01T12:00:00.000Z"],
["2026-09-01T05:00-07:00", "2026-09-01T12:00:00Z"],
["2026-09-01T24:00Z", "2026-09-02T00:00:00Z"],
["2026-09-01T24:00+05:30", "2026-09-02T00:00:00+05:30"],
])("preserves equal ISO instants %s and %s", (left, right) => {
expect(compareDateTimeStrings(left, right)).toBe(0);
});
it("sorts malformed values before valid values", () => {
expect(compareDateTimeStrings("invalid", "2026-09-01T12:00:00.000Z")).toBeLessThan(0);
expect(compareDateTimeStrings("2026-09-01T12:00:00.000Z", "invalid")).toBeGreaterThan(0);
});
it.each([
"2014-02-30",
"2014-03-02",
"2014-03-02T00:00:00",
"2014-03-02T00:00:00.000",
"03/02/2014",
"March 2, 2014",
"Sun, 02 Mar 2014 00:00:00 GMT",
"2014-03-02T00:00:00.000Z\n",
"2014-02-30T00:00:00.000Z",
"1900-02-29T00:00:00.000-07:00",
"2024-04-31T00:00:00.000+05:30",
"2024-03-02T12:00:00.000+24:00",
"2026-09-01T24:01:00Z",
"2026-09-01T24:00:01Z",
"2026-09-01T24:00:00.0001Z",
"2026-09-01T24:01Z",
"2026-09-01T25:00Z",
])("treats %s as malformed without native date guessing", (malformed) => {
const valid = "1970-01-01T00:00:00.000Z";
expect(compareDateTimeStrings(malformed, valid)).toBeLessThan(0);
expect(compareDateTimeStrings(valid, malformed)).toBeGreaterThan(0);
expect(compareDateTimeStrings(malformed, "invalid")).toBeLessThan(0);
expect(compareDateTimeStrings("invalid", malformed)).toBeGreaterThan(0);
expect(compareDateTimeStrings(malformed, malformed)).toBe(0);
});
it("uses code-unit order for malformed date-time strings", () => {
expect(compareDateTimeStrings("invalid-a", "invalid-B")).toBeGreaterThan(0);
expect(compareDateTimeStrings("invalid-B", "invalid-a")).toBeLessThan(0);
});
it("returns zero for equal malformed date-time strings", () => {
expect(compareDateTimeStrings("invalid", "invalid")).toBe(0);
});
it("gives every permutation of mixed values the same order", () => {
const early = "2026-09-01T12:00:00.000+14:00";
const late = "2026-09-01T00:00:00.000-12:00";
const malformed = "2026-09-01T06:invalid";
const expected = [malformed, early, late];
const permutations = [
[early, late, malformed],
[early, malformed, late],
[late, early, malformed],
[late, malformed, early],
[malformed, early, late],
[malformed, late, early],
];
for (const values of permutations) {
expect(values.toSorted(compareDateTimeStrings)).toEqual(expected);
}
});
});