arrakis-js
Version:
Arrakis Javascript client library
76 lines (75 loc) • 2.42 kB
JavaScript
/**
* GPS epoch start date (January 6, 1980 UTC)
*/
const GPS_EPOCH = new Date("1980-01-06T00:00:00Z").getTime() / 1000;
/**
* List of leap seconds added since GPS epoch
* This list needs to be updated when new leap seconds are added
* Source: https://www.iers.org/IERS/EN/DataProducts/EarthOrientationData/eop.html
*/
const LEAP_SECONDS = [
"1981-07-01",
"1982-07-01",
"1983-07-01",
"1985-07-01",
"1988-01-01",
"1990-01-01",
"1991-01-01",
"1992-07-01",
"1993-07-01",
"1994-07-01",
"1996-01-01",
"1997-07-01",
"1999-01-01",
"2006-01-01",
"2009-01-01",
"2012-07-01",
"2015-07-01",
"2017-01-01",
"2023-01-01",
];
/**
* Calculates the number of leap seconds that have been added up to a given date
* @param {Date} date - The date to calculate leap seconds for
* @returns {number} The number of leap seconds added up to the given date
*/
function calculateLeapSeconds(date) {
let totalLeapSeconds = 0;
for (const leapDate of LEAP_SECONDS) {
if (date >= new Date(leapDate)) {
totalLeapSeconds += 1;
}
else {
break;
}
}
return totalLeapSeconds;
}
/**
* Converts GPS time to Unix time (seconds since Jan 1, 1970)
* @param {number} gpsTime - GPS time in seconds since Jan 6, 1980 (can be negative for times before the GPS epoch)
* @returns {number} Unix time in seconds
* @throws {Error} If gpsTime is not a valid number
*/
export function gpsToUnix(gpsTime) {
if (typeof gpsTime !== "number" || isNaN(gpsTime)) {
throw new Error("GPS time must be a valid number");
}
const gpsDate = new Date((gpsTime + GPS_EPOCH) * 1000);
const totalLeapSeconds = calculateLeapSeconds(gpsDate);
return gpsTime + GPS_EPOCH + totalLeapSeconds;
}
/**
* Converts Unix time to GPS time (seconds since Jan 6, 1980)
* @param {number} unixTime - Unix time in seconds since Jan 1, 1970
* @returns {number} GPS time in seconds (can be negative for times before the GPS epoch)
* @throws {Error} If unixTime is not a valid number
*/
export function unixToGps(unixTime) {
if (typeof unixTime !== "number" || isNaN(unixTime)) {
throw new Error("Unix time must be a valid number");
}
const unixDate = new Date(unixTime * 1000);
const totalLeapSeconds = calculateLeapSeconds(unixDate);
return unixTime - GPS_EPOCH - totalLeapSeconds;
}