Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions core/util/historyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ import { getContinueGlobalPath } from "../util/paths.js";

// If useful elsewhere, helper funcs should move to core/util/index.ts or similar
function getOffsetDatetime(date: Date): Date {
const offset = date.getTimezoneOffset();
const offsetHours = Math.floor(offset / 60);
const offsetMinutes = offset % 60;
date.setHours(date.getHours() - offsetHours);
date.setMinutes(date.getMinutes() - offsetMinutes);

return date;
// Shift by the whole offset at once: splitting it into hours and minutes
// rounds the wrong way for zones east of UTC that aren't a whole number of
// hours ahead, e.g. UTC+05:30 would be treated as UTC+06:30.
return new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000);
}

function asBasicISOString(date: Date): string {
Expand Down
50 changes: 50 additions & 0 deletions core/util/historyUtils.vitest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import fs from "fs";
import os from "os";
import path from "path";

import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";

import { shareSession } from "./historyUtils";

describe("shareSession", () => {
const originalTz = process.env.TZ;
let outputDir: string;

const shareAt = async (timeZone: string, isoTime: string) => {
process.env.TZ = timeZone;
vi.useFakeTimers({ toFake: ["Date"] });
vi.setSystemTime(new Date(isoTime));

const ide = { writeFile: vi.fn(), openFile: vi.fn() };
const fileUrl = await shareSession(ide as any, [], outputDir);
return path.basename(fileUrl);
};

beforeEach(() => {
outputDir = fs.mkdtempSync(path.join(os.tmpdir(), "continue-share-"));
});

afterEach(() => {
vi.useRealTimers();
process.env.TZ = originalTz;
fs.rmSync(outputDir, { recursive: true, force: true });
});

it("names the file after local time in whole-hour timezones", async () => {
// UTC-04:00 in August
const name = await shareAt("America/New_York", "2026-08-17T10:00:00.000Z");
expect(name).toBe("20260817T060000_session.md");
});

it("names the file after local time in half-hour timezones", async () => {
// UTC+05:30
const name = await shareAt("Asia/Kolkata", "2026-08-17T10:00:00.000Z");
expect(name).toBe("20260817T153000_session.md");
});

it("names the file after local time in quarter-hour timezones", async () => {
// UTC+05:45
const name = await shareAt("Asia/Kathmandu", "2026-08-17T10:00:00.000Z");
expect(name).toBe("20260817T154500_session.md");
});
});
Loading