本文共 4491 字,大约阅读时间需要 14 分钟。
由于C标准库<ctime>(或者<time.h>)中,只支持1970年之后的日期。因此我自制了一个可以将日期转化为从公元1年1月1日0点0分0秒开始所经历的毫秒数,或者反过来将毫秒数转化为对应日期。
如有错漏,还望指摘。
class time_struct { public: time_struct() = default; time_struct(long long ms, int base_year = 1); long long ms_past_since(int base_year = 1) const; std::string print() const; bool is_leap_year() const; bool check_validity() const;private: long long ms_past_since_1() const; void set_time_by_ms(long long ms);public: short int year = 1; short int month = 1; short int day = 1; short int hour = 0; short int minute = 0; short int second = 0; short int milisecond = 0;};
void time_struct::set_time_by_ms(long long ms){ if (ms < 0) return; // milisecond milisecond = ms % 1000; ms /= 1000; // second second = ms % 60; ms /= 60; // minute minute = ms % 60; ms /= 60; // hour hour = ms % 24; ms /= 24; // How many 400 years are there year = (int)(ms / 146097) * 400; ms %= 146097; // How many 100 years are there // Since the last 100 years in a 400 years period // int num100years = ms / 36524; if (num100years == 4) { --num100years; ms -= 36524 * 3; } else { ms %= 36524; } year += num100years * 100; year += (int)(ms / 1461) * 4; ms %= 1461; int num1years = ms / 365; if (num1years == 4) { --num1years; ms -= 365 * 3; } else { ms %= 365; } year += num1years + 1; if (ms < 31) { month = 1; day = ms + 1; } else { if (is_leap_year()) { ms = ms - 31 + 2; month = (int)(ms * 12 / 367); day = ms - month * 367 / 12; day -= month ? 0 : 1; } else { ms = ms - 31 + 3; month = (int)(ms * 12 / 367); day = ms - month * 367 / 12; day -= month ? 0 : 2; } month += 2; }}
time_struct::time_struct(long long ms, int base_year){ time_struct base; base.year = base_year; set_time_by_ms(ms + base.ms_past_since_1());}
long long time_struct::ms_past_since_1() const{ if (!check_validity()) { // TODO: log // We assume LLONG_MIN is the error code return LLONG_MIN; } int temp_month = month - 2; int temp_year = year; if (0 >= temp_month) { /* 1..12 -> 11,12,1..10 */ temp_month += 12; /* Puts Feb last since it has leap day */ temp_year -= 1; } long long days = (long long)(temp_year / 4 - temp_year / 100 + temp_year / 400 + 367 * temp_month / 12 + day) + temp_year * 365 - 337; return (((( (long long)(temp_year / 4 - temp_year / 100 + temp_year / 400 + 367 * temp_month / 12 + day) + temp_year * 365 - 337 ) * 24 + hour /* now have hours */ ) * 60 + minute /* now have minutes */ ) * 60 + second /* now have seconds */ ) * 1000 + milisecond; /* millisecond */}
long long time_struct::ms_past_since(int base_year) const{ time_struct base; base.year = base_year; return this->ms_past_since_1() - base.ms_past_since_1();}
bool time_struct::is_leap_year() const{ return ((year % 4) || (!(year % 100) && (year % 400))) ? false : true;}
bool time_struct::check_validity() const{ if (year < 1) return false; if (day < 1) return false; switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: if (day > 31) return false; else break; case 4: case 6: case 9: case 11: if (day > 30) return false; else break; case 2: if (day > (is_leap_year() ? 29 : 28)) return false; else break; default: return false; } if (hour < 0 || hour > 23) return false; if (minute < 0 || minute > 59) return false; if (second < 0 || second > 59) return false; if (milisecond < 0 || milisecond > 999) return false; return true;}
string time_struct::print() const{ char buff[28]; sprintf_s( buff, "%04d-%02d-%02d %02d:%02d:%02d:%03d", year, month, day, hour, minute, second, milisecond ); return buff;}
转载地址:http://zxxzi.baihongyu.com/