fix(v0.5.1): use local time for workspace directory prefix and info display
Workspace directory names (YYYY-MM-DD_slug) and the YYYYMMDD-HHMMSS ID field now use local time so users see their wall-clock date rather than UTC — the prior behavior caused evening-EST creations to appear under tomorrow's date for several hours every day. ctask info's Created/Updated/Archived lines also convert to local for display. Stored timestamps in task.yaml, session logs, the lease, the manifest, and the session summary all continue to use UTC. Only user-facing surfaces change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+6
-3
@@ -35,8 +35,11 @@ func runInfo(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("Status: %s\n", m.Status)
|
||||
fmt.Printf("Mode: %s\n", m.Mode)
|
||||
fmt.Printf("Agent: %s\n", m.Agent)
|
||||
fmt.Printf("Created: %s\n", m.CreatedAt.Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("Updated: %s\n", m.UpdatedAt.Format("2006-01-02 15:04:05"))
|
||||
// v0.5.1: display timestamps in local time. task.yaml stores UTC;
|
||||
// info converts for friendliness so the shown time matches the user's
|
||||
// wall clock.
|
||||
fmt.Printf("Created: %s\n", m.CreatedAt.Local().Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("Updated: %s\n", m.UpdatedAt.Local().Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("Path: %s\n", ws.Path)
|
||||
|
||||
if m.LaunchDir != "" {
|
||||
@@ -56,7 +59,7 @@ func runInfo(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
if m.ArchivedAt != nil {
|
||||
fmt.Printf("Archived: %s\n", m.ArchivedAt.Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("Archived: %s\n", m.ArchivedAt.Local().Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
// List contents
|
||||
|
||||
@@ -88,6 +88,56 @@ func TestInfoOmitsLaunchFieldsForTask(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfoFormatsTimestampsInLocalZone(t *testing.T) {
|
||||
// v0.5.1: info must display Created/Updated/Archived in the local zone
|
||||
// so the displayed time matches the user's wall clock. The stored
|
||||
// timestamp stays UTC in task.yaml (unambiguous), but the display
|
||||
// converts for friendliness.
|
||||
root := t.TempDir()
|
||||
wsDir := filepath.Join(root, "general", "2026-04-22_tz-test")
|
||||
os.MkdirAll(wsDir, 0755)
|
||||
|
||||
// Pick a UTC moment that crosses a date boundary in most western zones.
|
||||
fixedUTC := time.Date(2026, 4, 23, 1, 22, 50, 0, time.UTC)
|
||||
archived := fixedUTC.Add(time.Hour)
|
||||
meta := &workspace.TaskMeta{
|
||||
ID: "t", Slug: "tz-test", Title: "tz-test",
|
||||
CreatedAt: fixedUTC, UpdatedAt: fixedUTC,
|
||||
ArchivedAt: &archived,
|
||||
Status: "archived", Category: "general", Type: "task",
|
||||
Mode: "local", Agent: "claude",
|
||||
}
|
||||
workspace.WriteMeta(filepath.Join(wsDir, "task.yaml"), meta)
|
||||
|
||||
// infoAll must be true because the workspace is archived.
|
||||
prevAll := infoAll
|
||||
infoAll = true
|
||||
defer func() { infoAll = prevAll }()
|
||||
|
||||
out, err := runInfoCapture(t, root, "tz-test")
|
||||
if err != nil {
|
||||
t.Fatalf("runInfo: %v", err)
|
||||
}
|
||||
|
||||
localCreated := fixedUTC.Local().Format("2006-01-02 15:04:05")
|
||||
utcCreated := fixedUTC.Format("2006-01-02 15:04:05")
|
||||
localArchived := archived.Local().Format("2006-01-02 15:04:05")
|
||||
|
||||
if !strings.Contains(out, "Created: "+localCreated) {
|
||||
t.Errorf("expected Created line to show local time %q:\n%s", localCreated, out)
|
||||
}
|
||||
if !strings.Contains(out, "Updated: "+localCreated) {
|
||||
t.Errorf("expected Updated line to show local time %q:\n%s", localCreated, out)
|
||||
}
|
||||
if !strings.Contains(out, "Archived: "+localArchived) {
|
||||
t.Errorf("expected Archived line to show local time %q:\n%s", localArchived, out)
|
||||
}
|
||||
// Only meaningful when local != UTC (skips when the test host is UTC).
|
||||
if localCreated != utcCreated && strings.Contains(out, "Created: "+utcCreated) {
|
||||
t.Errorf("Created line must not show UTC time %q when local differs (%q):\n%s", utcCreated, localCreated, out)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInfoShowsDirExistsNoWhenLaunchDirMissing(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
wsDir := filepath.Join(root, "projects", "2026-04-22_renamed")
|
||||
|
||||
Reference in New Issue
Block a user