Skip to content

Commit 8ed33d5

Browse files
committed
Handle numeric checklist completedTime values
1 parent 50ff24e commit 8ed33d5

2 files changed

Lines changed: 59 additions & 8 deletions

File tree

internal/ticktick/client.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ type tokenResponse struct {
3333
Scope string `json:"scope"`
3434
}
3535

36+
type TickTickTime string
37+
38+
func (t *TickTickTime) UnmarshalJSON(data []byte) error {
39+
if string(data) == "null" {
40+
*t = ""
41+
return nil
42+
}
43+
44+
var s string
45+
if err := json.Unmarshal(data, &s); err == nil {
46+
*t = TickTickTime(s)
47+
return nil
48+
}
49+
50+
var ms int64
51+
if err := json.Unmarshal(data, &ms); err == nil {
52+
*t = TickTickTime(time.UnixMilli(ms).UTC().Format("2006-01-02T15:04:05-0700"))
53+
return nil
54+
}
55+
56+
return fmt.Errorf("unsupported TickTick time value: %s", string(data))
57+
}
58+
3659
type Project struct {
3760
ID string `json:"id,omitempty"`
3861
Name string `json:"name,omitempty"`
@@ -46,14 +69,14 @@ type Project struct {
4669
}
4770

4871
type ChecklistItem struct {
49-
ID string `json:"id,omitempty"`
50-
Title string `json:"title,omitempty"`
51-
Status int `json:"status,omitempty"`
52-
CompletedTime string `json:"completedTime,omitempty"`
53-
IsAllDay bool `json:"isAllDay,omitempty"`
54-
SortOrder int64 `json:"sortOrder,omitempty"`
55-
StartDate string `json:"startDate,omitempty"`
56-
TimeZone string `json:"timeZone,omitempty"`
72+
ID string `json:"id,omitempty"`
73+
Title string `json:"title,omitempty"`
74+
Status int `json:"status,omitempty"`
75+
CompletedTime TickTickTime `json:"completedTime,omitempty"`
76+
IsAllDay bool `json:"isAllDay,omitempty"`
77+
SortOrder int64 `json:"sortOrder,omitempty"`
78+
StartDate string `json:"startDate,omitempty"`
79+
TimeZone string `json:"timeZone,omitempty"`
5780
}
5881

5982
type Task struct {

internal/ticktick/ticktime_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package ticktick
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
)
7+
8+
func TestChecklistItemCompletedTimeAcceptsUnixMillis(t *testing.T) {
9+
var item ChecklistItem
10+
err := json.Unmarshal([]byte(`{"completedTime":1764053112000,"title":"x"}`), &item)
11+
if err != nil {
12+
t.Fatalf("unmarshal failed: %v", err)
13+
}
14+
if item.CompletedTime == "" {
15+
t.Fatalf("completedTime should be populated")
16+
}
17+
}
18+
19+
func TestChecklistItemCompletedTimeAcceptsNull(t *testing.T) {
20+
var item ChecklistItem
21+
err := json.Unmarshal([]byte(`{"completedTime":null,"title":"x"}`), &item)
22+
if err != nil {
23+
t.Fatalf("unmarshal failed: %v", err)
24+
}
25+
if item.CompletedTime != "" {
26+
t.Fatalf("expected empty completedTime for null, got %q", item.CompletedTime)
27+
}
28+
}

0 commit comments

Comments
 (0)