diff --git a/minmea.c b/minmea.c index 960cbbe..6bcf0f3 100644 --- a/minmea.c +++ b/minmea.c @@ -619,7 +619,13 @@ int minmea_gettime(struct timespec *ts, const struct minmea_date *date, const st struct tm tm; memset(&tm, 0, sizeof(tm)); - tm.tm_year = 2000 + date->year - 1900; + if (date->year < 80) { + tm.tm_year = 2000 + date->year - 1900; // 2000-2079 + } else if (date->year >= 1900) { + tm.tm_year = date->year - 1900; // 4 digit year, use directly + } else { + tm.tm_year = date->year; // 1980-1999 + } tm.tm_mon = date->month - 1; tm.tm_mday = date->day; tm.tm_hour = time_->hours; diff --git a/tests.c b/tests.c index 9709114..4e90c44 100644 --- a/tests.c +++ b/tests.c @@ -953,10 +953,45 @@ START_TEST(test_minmea_gettime) d.year = -1; ck_assert(minmea_gettime(&ts, &d, &t) != 0); - d.year = 2014; + d.year = 14; t.hours = -1; ck_assert(minmea_gettime(&ts, &d, &t) != 0); + t.hours = 13; + + /* two digit year conversions */ + d.year = 80; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 319381209); /* 1980 */ + d.year = 37; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 2118229209); /* 2037 */ + /* skip >= 2038 tests on 32-bit time_t platforms */ + if (sizeof(time_t) == sizeof(int64_t)) { + d.year = 79; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 3443605209); /* 2079 */ + } + + /* four digit year conversions */ + d.year = 1979; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 287845209); + d.year = 1980; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 319381209); + d.year = 2037; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 2118229209); + /* skip >= 2038 tests on 32-bit time_t platforms */ + if (sizeof(time_t) == sizeof(int64_t)) { + d.year = 2079; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 3443605209); + d.year = 2080; + ck_assert(minmea_gettime(&ts, &d, &t) == 0); + ck_assert_int_eq(ts.tv_sec, 3475141209); + } } END_TEST