Skip to content
Merged
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
16 changes: 8 additions & 8 deletions server/internal/converter/csv_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand All @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions server/internal/converter/csv_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ 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)
}

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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Loading