GPS times reported in MAVLink messages are in two parts: The GPS week number, and the number of milliseconds since the start of that week. Also, need to know when GPS weeks started (Jan 6, 1980).
Here's a bit of javascript code that seems to work well for me (could easily be ported to other languages):
// no. of milliseconds in a date since midnight of
// January 1, 1970, according to UTC time;
// months are zero-based, but days are 1-based
var GPS_EPOCH_MILLIS = (new Date(1980, 0, 6, 0, 0, 0, 0)).getTime();
// all the leap seconds that have been defined so far;
// must keep this list current!
var leapSecondsMillis = [
(new Date(1981, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1982, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1983, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1985, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1988, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(1990, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(1991, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(1992, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1993, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1994, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1996, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(1997, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(1999, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(2006, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(2009, 0, 1, 0, 0, 0, 0)).getTime(),
(new Date(2012, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(2015, 6, 1, 0, 0, 0, 0)).getTime(),
(new Date(2017, 0, 1, 0, 0, 0, 0)).getTime()
];
// convert GPS time to a date & time object
var gpsTimeToDate = function(gpsWeek, millisIntoGPSWeek) {
return new Date(gpsTimeToMillis(gpsWeek, millisIntoGPSWeek));
};
// 604,800 seconds in a week (60 x 60 x 24 x 7)
var gpsTimeToMillis = function(gpsWeek, millisIntoGPSWeek) {
var millis = GPS_EPOCH_MILLIS + (gpsWeek * 604800000) + millisIntoGPSWeek;
// add leap seconds as appropriate
for (var leap in leapSecondsMillis)
if (millis >= leap)
millis -= 1000;
return millis;
};