Установка системного времени с помощью структуры gps timestamp_t в Linux

Установка системного времени с помощью структуры gps timestamp_t в Linux

Всем привет,

Я пытаюсь написать код, который, как только я получу успешную блокировку GPS (Adafruit Ultimate GPS с GPSD), устанавливает системное время. Прямо сейчас я вижу, что ‘timestamp_t’:

typedef double timestamp_t; /* Unix time in seconds with fractional part */

является частью моей структуры «gps_data_t *». Это хорошее начало, однако, функция, которую я планировал использовать для установки системного времени в Linux:

int settimeofday(const struct timeval *tv, const struct timezone *tz);

Я нашел информацию о том, как преобразовать time_t в * timeval, но как мне обработать этот дубль, чтобы преобразовать его в * timeval?

Код:

gpsmm gps_rec("localhost", DEFAULT_GPSD_PORT);

if (gps_rec.stream(WATCH_ENABLE|WATCH_JSON) == NULL) {
std::cout << "No GPSD running. exiting GPS thread." << std::endl;
return;
}

//Data structure
struct gps_data_t* newdata;

//Loop until first GPS lock to set system time
while ((newdata = gps_rec.read()) == NULL) {
//Wait for a valid read
}

//Set system time - timestamp_t vs timeval?
timeval *tv{?? newdata->time ??};
timezone *tz{ timezone(300, DST_USA)};
settimeofday(tv, tz);

Некоторые комментарии и ссылки помогли мне. Путаница заключается в различении timeval, time_t и timestamp_t. Насколько я понимаю, здесь есть различия, пожалуйста, исправьте, если не так:

Все время в секундах после 1 января 1970 года, но …

timeval — это структура из (2) длинных значений, tv_sec — секунды после 01.01.1970, tv_usec — микросекунды после этого.

time_t это долго? это также секунды после 01.01.1970

timestamp_t — это число, равное секундам после 1 января 1970 года, поэтому десятичная часть может вычислять микросекунды, чтобы получить «примерно» ту же точность времени.

Таким образом, преобразование между ними может быть таким:

timeval time;
time_t timet;
timestamp_t timestampt;

timet = time.tv_sec;   //usec dropped
timet = timestampt;    //usec dropped
timestampt = timet;    //usec not given
timestampt = time.tv_sec;
timestampt += (time.tv_usec / 1000000)  //Denominator may be off by a few 0's

Эта картина более ясная картина?


Чтобы пойти противоположным путем, что необходимо для моего приложения:

//Convert gps_data_t* member 'time' to timeval
timeval tv;
double wholeseconds, decimalseconds;
decimalseconds = modf(newdata->time, &wholeseconds);
tv.sec = static_cast<int32_t>(wholeseconds);
tv.usec = static_cast<int32_t>(decimalseconds * 1000000.0);

//Create timezone
timezone tz{ timezone(300, DST_USA)};

//Set system time
settimeofday(&tv, &tz);

1

Решение

Вот:

//Get first data to set system time
struct gps_data_t* firstdata;

//Loop until first GPS lock to set system time
while (((firstdata = gps_rec.read()) == NULL) ||
(firstdata->fix.mode < 1)) {
//Do nothing
}

//Convert gps_data_t* member 'time' to timeval
timeval tv;
double wholeseconds, decimalseconds, offsettime;
offsettime = firstdata->fix.time - (5.0 * 3600.0);  //5hr offset from GMT
decimalseconds = modf(offsettime, &wholeseconds);
tv.tv_sec = static_cast<int32_t>(wholeseconds);
tv.tv_usec = static_cast<int32_t>(decimalseconds * 1000000.0);

//Set system time
if ( settimeofday(&tv, NULL) >= 0) {
std::cout << "Time set succesful!" << '\n';
} else {
std::cout << "Time set failure!" << '\n';
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]