如何用boost::format正确格式化正负UTC偏移分钟数?
问题:使用boost::format格式化UTC分钟偏移量时负非整小时场景出错
需求是将以分钟为单位的UTC偏移量格式化为如下格式:
120: +0200 -120: -0200
我编写了如下实现函数:
void printData(const int dat) { std::string data; if (dat >= 0) { data = (boost::format("+%02d%02d") % (dat/60) % (dat%60)).str(); } else { data = (boost::format("%03d%02d") % (dat/60) % (dat%60)).str(); } std::cout<< " " << data << "\n"; }
该函数需要适配以下测试场景:
// 1: 0-10 (+, -) // 1.1 整小时 std::cout<<"1:\n"; std::cout<<"1.1:\n"; printData(540); // +9小时 -> 预期+0900,实际正常 printData(-540); // -9小时 -> 预期-0900,实际正常 printData(600); // +10小时 -> 预期+1000,实际正常 printData(-600); // -10小时 -> 预期-1000,实际正常 // 1.2 半小时 std::cout<<"1.2:\n"; printData(570); // +9:30小时 -> 预期+0930,实际正常 printData(-570); // -9:30小时 -> 预期-0930,实际输出-09-30,错误 // 1.3 45分钟 std::cout<<"1.3:\n"; printData(585); // +9:45小时 -> 预期+0945,实际正常 printData(-585); // -9:45小时 -> 预期-0945,实际输出-09-45,错误 std::cout<<"\n"; std::cout<<"\n2:\n"; // 2: 11-14 (+, -): // 2.1 整小时 std::cout<<"2.1:\n"; printData(660); // +11小时 -> 预期+1100,实际正常 printData(-660); // -11小时 -> 预期-1100,实际正常 // 2.2 半小时 std::cout<<"2.2:\n"; printData(690); // +11:30小时 -> 预期+1130,实际正常 printData(-690); // -11:30小时 -> 预期-1130,实际输出-11-30,错误 // 2.3 45分钟 std::cout<<"2.3:\n"; printData(705); // +11:45小时 -> 预期+1145,实际正常 printData(-705); // -11:45小时 -> 预期-1145,实际输出-11-45,错误 std::cout<<"\n";
但处理非整小时的负偏移量时出现格式错误,请问是否可以通过boost::format适配所有测试用例?
解决方案:可以通过boost::format适配所有测试用例
问题根源在于C++中负数取模的结果符号与被除数一致,比如-570 % 60的结果是-30,导致格式化时出现多余的负号。只需调整计算逻辑,确保分钟部分为正数,再统一处理符号即可。
修改后的实现方式1:分离符号与数值计算
#include <cstdlib> // 用于std::abs void printData(const int dat) { int abs_dat = std::abs(dat); int hours = abs_dat / 60; int mins = abs_dat % 60; // 根据原偏移量的符号选择前缀,格式化小时和分钟为两位数字 std::string data = (boost::format("%c%02d%02d") % (dat >= 0 ? '+' : '-') % hours % mins).str(); std::cout << " " << data << "\n"; }
修改后的实现方式2:利用数值格式化特性
#include <cstdlib> void printData(const int dat) { int abs_dat = std::abs(dat); int total_hundredths = (abs_dat / 60) * 100 + (abs_dat % 60); // %+05d 会自动添加正负号,并确保总长度为5(包含符号),不足补零 std::string data = (boost::format("%+05d") % (dat >= 0 ? total_hundredths : -total_hundredths)).str(); std::cout << " " << data << "\n"; }
两种方式都能正确处理所有测试场景,包括非整小时的负偏移量,输出符合预期的格式。
内容的提问来源于stack exchange,提问作者Klg klg
相关产品推荐
相关产品推荐

