diff --git a/server/internal/converter/csv_parser.go b/server/internal/converter/csv_parser.go index a88f363..6106f53 100644 --- a/server/internal/converter/csv_parser.go +++ b/server/internal/converter/csv_parser.go @@ -17,7 +17,7 @@ func init() { // Format: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING // Example: 1,T,260417,110529,52.4194759N,13.3076437E,62,1.4,333 // -// - DATE is ddmmyy (UTC) +// - DATE is yymmdd (UTC) // - TIME is hhmmss (UTC) // - LATITUDE: decimal degrees with N/S suffix // - LONGITUDE: decimal degrees with E/W suffix @@ -79,7 +79,7 @@ func parseCSVRow(record []string, lineNum int) (Point, error) { } point.Lon = lon - // Parse date + time (ddmmyy + hhmmss, UTC) + // Parse date + time (yymmdd + hhmmss, UTC) t, err := parseDateTime(record[2], record[3]) if err != nil { return point, fmt.Errorf("row %d: datetime: %w", lineNum, err) @@ -141,7 +141,7 @@ func parseCoordinate(s string) (float64, error) { } } -// parseDateTime parses ddmmyy + hhmmss into time.Time (UTC). +// parseDateTime parses yymmdd + hhmmss into time.Time (UTC). func parseDateTime(dateStr, timeStr string) (time.Time, error) { if len(dateStr) != 6 { return time.Time{}, fmt.Errorf("expected 6-char date, got %q", dateStr) @@ -150,19 +150,19 @@ func parseDateTime(dateStr, timeStr string) (time.Time, error) { return time.Time{}, fmt.Errorf("expected 6-char time, got %q", timeStr) } - day, err := strconv.Atoi(dateStr[0:2]) + year, err := strconv.Atoi(dateStr[0:2]) if err != nil { - return time.Time{}, fmt.Errorf("invalid day in %q", dateStr) + return time.Time{}, fmt.Errorf("invalid year in %q", dateStr) } + year += 2000 // 2-digit year month, err := strconv.Atoi(dateStr[2:4]) if err != nil { return time.Time{}, fmt.Errorf("invalid month in %q", dateStr) } - year, err := strconv.Atoi(dateStr[4:6]) + day, err := strconv.Atoi(dateStr[4:6]) if err != nil { - return time.Time{}, fmt.Errorf("invalid year in %q", dateStr) + return time.Time{}, fmt.Errorf("invalid day in %q", dateStr) } - year += 2000 // 2-digit year hour, err := strconv.Atoi(timeStr[0:2]) if err != nil { diff --git a/server/internal/converter/csv_parser_test.go b/server/internal/converter/csv_parser_test.go index 05f394e..7788811 100644 --- a/server/internal/converter/csv_parser_test.go +++ b/server/internal/converter/csv_parser_test.go @@ -24,7 +24,7 @@ func TestCSVParser_SampleData(t *testing.T) { p := tracks[0].Segments[0].Points[0] assert.InDelta(t, 52.5249440, p.Lat, 0.0000001) assert.InDelta(t, 13.3693610, p.Lon, 0.0000001) - assert.Equal(t, time.Date(2017, 4, 26, 11, 5, 29, 0, time.UTC), *p.Time) + assert.Equal(t, time.Date(2026, 4, 17, 11, 5, 29, 0, time.UTC), *p.Time) assert.InDelta(t, 38.0, *p.Elevation, 0.1) assert.InDelta(t, 1.4/3.6, *p.Speed, 0.001) // km/h -> m/s assert.InDelta(t, 333.0, *p.Course, 0.1) @@ -32,7 +32,7 @@ func TestCSVParser_SampleData(t *testing.T) { func TestCSVParser_SouthWest(t *testing.T) { data := `INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING -1,T,010120,120000,33.8688197S,151.2092955W,5,0.0,0 +1,T,200101,120000,33.8688197S,151.2092955W,5,0.0,0 ` tracks, err := (&csvParser{}).Parse([]byte(data)) require.NoError(t, err) @@ -43,7 +43,7 @@ func TestCSVParser_SouthWest(t *testing.T) { func TestCSVParser_SpeedConversion(t *testing.T) { data := `INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING -1,T,010120,120000,50.0N,10.0E,100,36.0,90 +1,T,200101,120000,50.0N,10.0E,100,36.0,90 ` tracks, err := (&csvParser{}).Parse([]byte(data)) require.NoError(t, err) @@ -84,7 +84,7 @@ func TestCSVParser_InvalidCoordinate(t *testing.T) { func TestCSVParser_DateParsing(t *testing.T) { data := `INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING -1,T,010125,235959,50.0N,10.0E,100,0.0,0 +1,T,250101,235959,50.0N,10.0E,100,0.0,0 ` tracks, err := (&csvParser{}).Parse([]byte(data)) require.NoError(t, err) @@ -130,5 +130,5 @@ func TestParseCoordinate(t *testing.T) { func TestParseDateTime(t *testing.T) { dt, err := parseDateTime("260417", "110529") require.NoError(t, err) - assert.Equal(t, time.Date(2017, 4, 26, 11, 5, 29, 0, time.UTC), dt) + assert.Equal(t, time.Date(2026, 4, 17, 11, 5, 29, 0, time.UTC), dt) }