C++计算到GMT午夜12点剩余秒数的实现方案
问题描述
需要实现一个返回秒级时长的函数,计算从应用部署启动时刻到GMT时区午夜12:00 AM的剩余时间,到达该时间点时应用将触发执行特定操作。现有实现仅能计算固定12小时、24小时偏移后的时间,无法准确获取到下一个GMT午夜零点的剩余时长,当前测试代码如下:
#include <iostream> #include <iomanip> #include <ctime> #include <chrono> int main() { using namespace std::literals; // 支持直接使用24h、1ms、1s这类字面量,无需再写std::chrono::hours(24)这类长格式 const std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now(); const std::time_t t_c = std::chrono::system_clock::to_time_t(now - 24h); std::cout << "24小时前的时间为 " << std::put_time(std::localtime(&t_c), "%F %T.\n") << std::flush; const std::time_t t_c_12 = std::chrono::system_clock::to_time_t(now + 12h); std::cout << "12小时后的时间为 " << std::put_time(std::localtime(&t_c_12), "%F %T.\n") << std::flush; }
实现方案
不需要做复杂的日期递推,按以下逻辑计算即可:
- 必须使用GMT时区接口拆解当前时间,不能用
std::localtime这类本地时区接口,否则会混入时区偏移导致结果错误 - 从拆解后的GMT时间结构中,取出当前的时、分、秒字段,累加得到当日从0点开始已经流逝的秒数
- 用单日总秒数86400减去已流逝的秒数,得到的就是到下一个GMT午夜12:00的剩余秒数,精度符合要求,可直接用于定时触发逻辑
注意:
std::gmtime返回的是指向静态内存的指针,拿到结果后要立即拷贝到本地tm结构体,避免后续时间接口调用覆盖该内存区域的值导致计算错误。
完整可运行代码
#include <iostream> #include <iomanip> #include <ctime> #include <chrono> // 返回到下一个GMT午夜12:00的剩余秒数 long long get_seconds_to_gmt_midnight() { using namespace std::chrono; const auto now = system_clock::now(); const std::time_t now_t = system_clock::to_time_t(now); // 转换为GMT时区时间,禁止使用localtime const std::tm gmt_now = *std::gmtime(&now_t); // 计算当日已过秒数 const long long elapsed = gmt_now.tm_hour * 3600LL + gmt_now.tm_min * 60LL + gmt_now.tm_sec; // 返回剩余秒数 return 86400LL - elapsed; } int main() { using namespace std::literals; const auto now = std::chrono::system_clock::now(); // 原有测试逻辑保留 const std::time_t t_c = std::chrono::system_clock::to_time_t(now - 24h); std::cout << "24小时前的时间为 " << std::put_time(std::localtime(&t_c), "%F %T.\n") << std::flush; const std::time_t t_c_12 = std::chrono::system_clock::to_time_t(now + 12h); std::cout << "12小时后的时间为 " << std::put_time(std::localtime(&t_c_12), "%F %T.\n") << std::flush; // 新增GMT午夜剩余时间计算 const long long remain_sec = get_seconds_to_gmt_midnight(); const auto midnight_tp = now + std::chrono::seconds(remain_sec); const std::time_t midnight_t = std::chrono::system_clock::to_time_t(midnight_tp); std::cout << "距离下一个GMT午夜的剩余秒数:" << remain_sec << "秒\n"; std::cout << "下一个GMT午夜的时间为 " << std::put_time(std::gmtime(&midnight_t), "%F %T GMT.\n") << std::flush; return 0; }
内容的提问来源于stack exchange,提问作者RAGHUVARAN
相关产品推荐
相关产品推荐

