我正在嵌入式Linux上工作,自1970年1月1日以来,系统/ Controller 的时间以毫秒为单位。我正在尝试使用gmtime,但无法获得准确的结果。将这个时间(毫秒)转换为实时小时:分钟:秒:天:月的任何示例都将有所帮助。
最佳答案
您可以使用在Howard Hinnant的chrono-Compatible Low-Level Date Algorithms中派生并详细解释的civil_from_days
。此函数自1970年1月1日开始需要花费几天的时间,并将其转换为{y, m, d}
字段。完成此操作后,您只需要从毫秒时间戳中减去天数即可获得自午夜以来的毫秒数,然后将其分解为h:M:s.ms
。
这是完整的代码:
#include <iostream>
#include <iomanip>
#include <cstdint>
int
main()
{
using namespace std;
int64_t t = 1490285505123; // milliseconds since epoch
int32_t z = (t >= 0 ? t : t - (1000*86400-1))/(1000*86400); // days since epoch
t -= z * (1000LL * 86400); // milliseconds since midnight
z += 719468;
int32_t era = (z >= 0 ? z : z - 146096) / 146097;
int32_t doe = z - era * 146097;
int32_t yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;
int32_t y = yoe + era * 400;
int32_t doy = doe - (365*yoe + yoe/4 - yoe/100);
int32_t m = (5*doy + 2)/153;
int32_t d = doy - (153*m + 2)/5 + 1; // day
m += m < 10 ? 3 : -9; // month
y += m <= 2; // year
int32_t h = t / (1000 * 3600); // hour
t -= h * (1000 * 3600);
int32_t M = t / (1000 * 60); // minute
t -= M * (1000 * 60);
int32_t s = t / 1000; // second
int32_t ms = t - s * 1000; // ms
cout.fill('0');
cout << setw(4) << y << '-' << setw(2) << m << '-' << setw(2) << d
<< ' ' << setw(2) << h << ':' << setw(2) << M
<< ':' << setw(2) << s << '.' << setw(3) << ms << '\n';
}
仅作为示例,我已使用
1490285505123ms
作为输入,输出为:2017-03-23 16:11:45.123
这考虑了leap年。无需考虑leap秒。嵌入式Linux系统/ Controller 极不可能做到这一点,因此尝试这样做是不正确的。
上面的算法对
t
的有效性范围非常大:-5877641-06-23 00:00:00.000 <= t <= 5880010-09-09 23:59:59.999
(+/- 580万年)
如果您不介意将
t
的下限限制为0000-03-01 00:00:00.000
,则可以将era
的计算简化为:int32_t era = z / 146097;
如果可以将
t
的下限限制为1970-01-01 00:00:00.000
,则可以将z
的计算简化为:int32_t z = t / (1000 * 86400); // days since epoch
最后,如果您愿意将
t
限制在这400年范围内:2000-03-01 00:00:00.000 <= t <= 2400-02-29 23:59:59.999
然后
era
可以简单地变成:int32_t const era = 5;
首先,这是一个high-level date/time library,它利用C++ 11/14
<chrono>
库执行完全相同的计算,只是语法更简洁。您的std::lib必须支持<chrono>
才能使用此库:#include "date.h"
#include <iostream>
int
main()
{
using namespace date;
using namespace std;
using namespace std::chrono;
cout << sys_time<milliseconds>(1490285505123ms) << '\n';
}
关于c++ - gmtime()函数是否考虑leap年?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42964040/