Skip to content

Commit

Permalink
DateTime function to convert to time.Time value (close #115) (#116)
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt authored Aug 8, 2024
1 parent a11a9ab commit af41c6a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
19 changes: 19 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
"unicode"
)

Expand Down Expand Up @@ -384,6 +385,24 @@ func ParseDate(ddmmyy string) (Date, error) {
return Date{true, dd, mm, yy}, nil
}

// DateTime converts the provided Date and Time values to a standard UTC time.Time.
// The referenceYear parameter is used to determine the offset (century) for the two-digit year in Date.
// For example, if the referenceYear is 2024, the offset used is 2000; and the input date's year is prepended with 20.
// If referenceYear is 0, the current UTC year is used.
// If either Date or Time is not valid, DateTime returns the zero time.Time.
func DateTime(referenceYear int, d Date, t Time) time.Time {
if !d.Valid || !t.Valid {
return time.Time{}
}
if referenceYear == 0 {
referenceYear = time.Now().UTC().Year()
}
century := referenceYear / 100 * 100 // truncate the last two digits (year within century); keep first two digits of the full year
return time.Date(century+d.YY, time.Month(d.MM), d.DD,
t.Hour, t.Minute, t.Second, t.Millisecond*1e6,
time.UTC)
}

// LatDir returns the latitude direction symbol
func LatDir(l float64) string {
if l < 0.0 {
Expand Down
55 changes: 55 additions & 0 deletions types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nmea
import (
"fmt"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -220,6 +221,60 @@ func TestDateString(t *testing.T) {
}
}

func TestDateTime(t *testing.T) {
for i, testCase := range []struct {
refYear int
date Date
time Time
expect time.Time
}{
{
refYear: 2024,
date: Date{DD: 1, MM: 2, YY: 3, Valid: true},
time: Time{Hour: 1, Minute: 2, Second: 3, Millisecond: 4, Valid: true},
expect: time.Date(2003, time.February, 1, 1, 2, 3, 4e6, time.UTC),
},
{
refYear: 1999,
date: Date{DD: 1, MM: 2, YY: 3, Valid: true},
time: Time{Hour: 1, Minute: 2, Second: 3, Millisecond: 4, Valid: true},
expect: time.Date(1903, time.February, 1, 1, 2, 3, 4e6, time.UTC),
},
{
refYear: 2025,
date: Date{DD: 23, MM: 7, YY: 24, Valid: true},
time: Time{Hour: 18, Minute: 5, Second: 12, Millisecond: 1, Valid: true},
expect: time.Date(2024, time.July, 23, 18, 5, 12, 1e6, time.UTC),
},
// zero reference year; this test will fail starting in the year 3000
{
refYear: 0,
date: Date{DD: 1, MM: 2, YY: 3, Valid: true},
time: Time{Hour: 1, Minute: 2, Second: 3, Millisecond: 4, Valid: true},
expect: time.Date(2003, time.February, 1, 1, 2, 3, 4e6, time.UTC),
},
// invalid date
{
refYear: 2024,
date: Date{DD: 1, MM: 2, YY: 3},
time: Time{Hour: 1, Minute: 2, Second: 3, Millisecond: 4, Valid: true},
expect: time.Time{},
},
// invalid time
{
refYear: 2024,
date: Date{DD: 1, MM: 2, YY: 3, Valid: true},
time: Time{Hour: 1, Minute: 2, Second: 3, Millisecond: 4},
expect: time.Time{},
},
} {
actual := DateTime(testCase.refYear, testCase.date, testCase.time)
if !actual.Equal(testCase.expect) {
t.Fatalf("Test %d (refYear=%d date=%s time=%s): Expected %s but got %s", i, testCase.refYear, testCase.date, testCase.time, testCase.expect, actual)
}
}
}

func TestLatDir(t *testing.T) {
tests := []struct {
value float64
Expand Down

0 comments on commit af41c6a

Please sign in to comment.