Skip to content

Commit 9bb7673

Browse files
committed
fix: improve EXIF date parsing and add comprehensive test cases
1 parent ca09e66 commit 9bb7673

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

internal/exif/direct.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,12 @@ func readDateTime(x *exif.Exif, dateTag exif.FieldName, subSecTag exif.FieldName
177177
}
178178

179179
func parseExifTime(date string, local *time.Location) (time.Time, error) {
180+
date = strings.TrimSpace(date)
180181
var year, month, day, hour, minutes, sec, milli int
181182
date = strings.ReplaceAll(date, "-", ":")
182183
date = strings.ReplaceAll(date, "/", ":")
183184
_, err := fmt.Sscanf(date, "%d:%d:%d %d:%d:%d.%d", &year, &month, &day, &hour, &minutes, &sec, &milli)
184-
if err != nil || year < 1900 || month == 0 || day == 0 {
185+
if (err != nil && err.Error() != "unexpected EOF") || year < 1900 || month == 0 || day == 0 {
185186
return time.Time{}, fmt.Errorf("invalid date format")
186187
}
187188
d := time.Date(year, time.Month(month), day, hour, minutes, sec, milli*int(time.Millisecond), local)

internal/exif/direct_test.go

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,68 @@ func Test_parseExifTime(t *testing.T) {
9090
wantErr bool
9191
}{
9292
{
93-
name: "valid date with different separators in local timezone",
93+
name: "valid date with different separators in local timezone",
9494
date: "2023-10-06 08:30:00",
9595
location: time.Local,
9696
want: time.Date(2023, 10, 6, 8, 30, 0, 0, time.Local),
9797
wantErr: false,
9898
},
9999
{
100-
name: "valid date with milliseconds in local timezone",
100+
name: "valid date with milliseconds in local timezone",
101101
date: "2023-10-06 08:30:00.123",
102102
location: time.Local,
103103
want: time.Date(2023, 10, 6, 8, 30, 0, int(123*time.Millisecond), time.Local),
104104
wantErr: false,
105105
},
106+
{
107+
name: "valid date with different separators in UTC timezone",
108+
date: "2023-10-06 08:30:00",
109+
location: time.UTC,
110+
want: time.Date(2023, 10, 6, 8, 30, 0, 0, time.UTC),
111+
wantErr: false,
112+
},
113+
{
114+
name: "valid date with milliseconds in UTC timezone",
115+
date: "2023/10/06 08:30:00.123",
116+
location: time.UTC,
117+
want: time.Date(2023, 10, 6, 8, 30, 0, int(123*time.Millisecond), time.UTC),
118+
wantErr: false,
119+
},
120+
{
121+
name: "date format with different separators",
122+
date: "2023/10/06 08:30:00",
123+
location: time.Local,
124+
want: time.Date(2023, 10, 6, 8, 30, 0, 0, time.Local),
125+
wantErr: false,
126+
},
127+
{
128+
name: "date format with milliseconds",
129+
date: "2023/10/06 08:30:00.123",
130+
location: time.Local,
131+
want: time.Date(2023, 10, 6, 8, 30, 0, int(123*time.Millisecond), time.Local),
132+
wantErr: false,
133+
},
134+
{
135+
name: "empty date string",
136+
date: "",
137+
location: time.Local,
138+
want: time.Time{},
139+
wantErr: true,
140+
},
141+
{
142+
name: "date string with extra spaces",
143+
date: " 2023-10-06 08:30:00 ",
144+
location: time.Local,
145+
want: time.Date(2023, 10, 6, 8, 30, 0, 0, time.Local),
146+
wantErr: false,
147+
},
148+
{
149+
name: "date string with extra spaces and milliseconds",
150+
date: " 2023-10-06 08:30:00.123 ",
151+
location: time.Local,
152+
want: time.Date(2023, 10, 6, 8, 30, 0, int(123*time.Millisecond), time.Local),
153+
wantErr: false,
154+
},
106155
}
107156
for _, tt := range tests {
108157
t.Run(tt.name, func(t *testing.T) {

0 commit comments

Comments
 (0)