ACE_OS::_make__time64_t 函数解析与时间转换

3星 · 超过75%的资源 需积分: 50 18 下载量 164 浏览量 更新于2024-09-15 收藏 5KB TXT 举报
"ACE_OS::mktime函数源代码解析" ACE_OS::mktime是一个用于将结构体tm转换为时间戳的函数,它在C++ ACE库中被实现。该函数的目的是将用户提供的日期和时间信息(以struct tm的形式)转换成自1970年1月1日00:00:00 UTC以来的秒数。在这个过程中的源代码涉及到多个步骤来确保计算的准确性和有效性。 首先,函数通过验证输入参数tb(一个struct tm指针)是否非空来确保输入的合法性。如果输入无效,函数会返回一个错误值。 接下来,源代码对年份进行检查,确保tm_year值在可接受范围内。年份需要在_BASE_YEAR(通常为1900)与_MAX_YEAR64+1之间,以避免超出计算范围。 然后,代码调整月份值,使其在0到11之间,这是因为超过12的月份没有定义天数。同时,如果月份小于0,会将月份加12并减去1年,以确保年份的正确性,并再次检查年份是否在有效范围内。 接着,计算当前年份到指定月份的天数,考虑闰年的情况。闰年的判断通过_IS_LEAP_YEAR函数完成,如果当前年份是闰年且月份大于1,则增加一天。 进一步,函数计算自1970年以来的总天数、小时数、分钟数和秒数。这涉及到一系列的乘法和加法运算,以将日期和时间信息转换为总的秒数。 在计算过程中,还考虑了时区和夏令时的影响。如果ultflag为真,会调用_tzset获取本地时区信息,然后使用_get_dstbias和_get_timezone函数分别获取夏令时偏移和时区偏移,将这些值加到总秒数上。最后,通过_localtime64_s函数将时间戳转换回struct tm格式,并根据tm_isdst字段处理夏令时。 如果在任何阶段出现错误,如输入非法或计算结果超出范围,函数会跳转到err_mktime标签,返回一个错误标识。 这个函数是ACE库中的关键部分,用于在ACE_OS层面上提供跨平台的时间处理能力,它遵循标准C的时间函数行为,并增加了对64位时间戳的支持。通过这个源代码,我们可以看到日期和时间转换背后的复杂逻辑,以及如何处理不同环境下的时区和夏令时问题。

#include<iostream> #include<ctime> #include<chrono> #include<string> #include<filesystem> #include<fstream> #include<sstream> #include<thread> #include<boost/filesystem.hpp> const uintmax_t MAX_LOGS_SIZE = 10ull * 1024ull * 1024ull * 1024ull; //const uintmax_t MAX_LOGS_SIZE = 10ull; void create_folder(std::string folder_name) { boost::filesystem::create_directory(folder_name); std::string sub_foldername=folder_name+"/logs_ros"; boost::filesystem::create_directory(sub_foldername); } std::string get_current_time() { auto now = std::chrono::system_clock::now(); std::time_t now_c = std::chrono::system_clock::to_time_t(now); std::tm parts = *std::localtime(&now_c); char buffer[20]; std::strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M", &parts); return buffer; } void check_logs_size() { std::string logs_path = "/home/sage/logs/"; boost::filesystem::path logs_dir(logs_path); std::uintmax_t total_size = 0; for (const auto& file : boost::filesystem::recursive_directory_iterator(logs_dir)) { if (boost::filesystem::is_regular_file(file)) { total_size += boost::filesystem::file_size(file); } } if (total_size > MAX_LOGS_SIZE) { boost::filesystem::path earliest_dir; std::time_t earliest_time = std::time(nullptr); for (const auto& dir : boost::filesystem::directory_iterator(logs_dir)) { if (boost::filesystem::is_directory(dir)) { std::string dir_name = dir.path().filename().string(); std::tm time_parts = {}; std::istringstream ss(dir_name); std::string part; std::getline(ss, part, '-'); time_parts.tm_year = std::stoi(part) - 1900; std::getline(ss, part, '-'); time_parts.tm_mon = std::stoi(part) - 1; std::getline(ss, part, '-'); time_parts.tm_mday = std::stoi(part); std::getline(ss, part, '-'); time_parts.tm_hour = std::stoi(part); std::getline(ss, part, '-'); time_parts.tm_min = std::stoi(part); std::time_t dir_time = std::mktime(&time_parts); if (dir_time < earliest_time) { earliest_time = dir_time; earliest_dir = dir.path(); } } } if (!earliest_dir.empty()) { boost::filesystem::remove_all(earliest_dir); } } } int main() { std::string logs_path = "/home/sage/logs/"; while (true) { std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::time_t now_c = std::chrono::system_clock::to_time_t(now); std::tm parts = *std::localtime(&now_c); if (parts.tm_min % 10 == 0) { std::string folder_name = logs_path + get_current_time(); create_folder(folder_name); } check_logs_size(); std::this_thread::sleep_for(std::chrono::minutes(1)); } return 0; }修改为ros节点

2023-06-09 上传