c++重载localtime函数
本文原创,转载请注明:https://www.cnblogs.com/tkblack/p/11274022.html
最近在写一个EOS的合约,我想将时间戳转换成日期,并将日期以整型存储,本来想采用localtime()或者gmtime()函数来直接转换,但是很遗憾,eosio.cdt好像并不支持该函数,虽然库当中具有该函数,但是实际编译还是会报错。然后我去github上面查看了eosio.cdt项目的相关issue,有人提出了这个问题,确实是编译的时候会报错;有开发者建议定义time_point或者time_point_sec类型,并将其存储在多索引表(multi_index)中,这样在展示的时候会以日期的格式打印。以上方法其实不是很契合我的需求,于是决定重载该函数,去网上看了看,发现有不少实现,但是很多人对于“百年不闰,四百年再闰”这点没有注意,他们的代码在2100年之前也是没有问题的(因为2100年是平年)。
好了,我们直接贴上代码:
/*** *重载localtime() *时间戳转换成日期(北京时间,东八区) ***/ int localtime(const time_t stamp, struct tm &ret_tm, int time_zone = 8) { static const int days_every_month[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 }; //平年各月份天数 static const bool four_year[4] = { false, false, true, false }; //1970开始,判断是否为闰年,4年为周期 static const bool four_hundred_year[4] = { true, false, false, false }; //百年不闰,四百年再闰 //int time_zone = 8; //多8小时 time_t timestamp = stamp + time_zone * 3600; ret_tm.tm_isdst = 0; //夏时令,这个东西没用过,默认是0,不过以防万一,还是重置下 //计算秒 ret_tm.tm_sec = (int)(timestamp % 60); int tmp = (int)(timestamp / 60); //计算分 ret_tm.tm_min = tmp % 60; tmp = tmp / 60; //计算时 ret_tm.tm_hour = tmp % 24; tmp = tmp / 24; /*** //1970.1.1到2000.1.1,一共历时10957天 //4年1461天,1461*24 = 35064小时 //100年36524或36525天 //400年146097天 ***/ int four_year_count = 0; //四年计数 int four_hundred_year_count = 0; //四百年计数 int left_days = 0; //剩余天数 int leave_years = 0; //过去年数 if (tmp > 10957) { four_hundred_year_count = (tmp - 10957) / 146097; //过去多少个400年,相对于2000.1.1而言 left_days = (tmp - 10957) % 146097; int i = 0; //此处i表示过了多少个百年,例如2100年1月1日,正好过100年,i == 1 for (; i < 4; ++i) { int hundred_year_days = four_hundred_year[i] ? 36525 : 36524; if (left_days < hundred_year_days) break; left_days -= hundred_year_days; } if (i >= 1 && left_days <= 58) i--; //当日期小于等于2月28日时,意味着这个百年并未多算一天,i-- tmp += (four_hundred_year_count * 3 + i); //将多算的天数补上 } four_year_count = tmp / 1461; //过去多少个4年 left_days = tmp % 1461; int i = 0; //i表示以4年为周期计数完之后,还过了几年 for (; i < 4; ++i) { int year_days = four_year[i] ? 366 : 365; if (left_days < year_days) break; left_days -= year_days; } //年 leave_years = (four_year_count << 2) + 1970 + i; ret_tm.tm_year = leave_years; int j = 0; for (; j < 12; ++j) { int month_days = days_every_month[j]; if (i == 2 && j == 1) { month_days++; } if (left_days < month_days) { break; } left_days -= month_days; } //月 ret_tm.tm_mon = j + 1; //日 ret_tm.tm_mday = left_days + 1; cout << ret_tm.tm_year << "." << ret_tm.tm_mon << "." << ret_tm.tm_mday << " " << ret_tm.tm_hour << ":" << ret_tm.tm_min << ":" << ret_tm.tm_sec << endl; return 0; }
以上代码,我仅进行简单测试,贴出来仅想和大家一起学习讨论,如果大家有什么更好的实现,或者代码逻辑有错误的地方,欢迎大家指正!