在 Linux 中使用 gps timestamp_t 结构设置系统时间
Setting system time with gps timestamp_t structure in Linux
在 Linux
中使用 gps timestamp_t 结构设置系统时间
大家好,
我正在尝试编写代码,以便在获得成功的 GPS 锁定(带 GPSD 的 Adafruit Ultimate GPS)后立即设置系统时间。现在,我可以看到 '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。据我了解,这里有不同之处,如果不是这样请更正:
所有时间都是 1970 年 1 月 1 日之后的秒数,但是...
timeval 是 (2) 个 long 值的结构,tv_sec 是 1/1/1970 之后的秒数,tv_usec 是之后的微秒数。
time_t是长?这也是 1/1/1970
之后的秒数
timestamp_t 是 1970 年 1 月 1 日之后的秒数,因此小数部分可以计算微秒以获得 'roughly' 与 timeval 相同的精度。
所以它们之间的转换可以这样进行:
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);
这里是:
//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';
}
在 Linux
中使用 gps timestamp_t 结构设置系统时间大家好,
我正在尝试编写代码,以便在获得成功的 GPS 锁定(带 GPSD 的 Adafruit Ultimate GPS)后立即设置系统时间。现在,我可以看到 '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。据我了解,这里有不同之处,如果不是这样请更正:
所有时间都是 1970 年 1 月 1 日之后的秒数,但是...
timeval 是 (2) 个 long 值的结构,tv_sec 是 1/1/1970 之后的秒数,tv_usec 是之后的微秒数。
time_t是长?这也是 1/1/1970
之后的秒数timestamp_t 是 1970 年 1 月 1 日之后的秒数,因此小数部分可以计算微秒以获得 'roughly' 与 timeval 相同的精度。
所以它们之间的转换可以这样进行:
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);
这里是:
//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';
}