gmtime() 函数是否考虑了闰年?
Does gmtime() function take into account leap years?
我正在研究嵌入式Linux,自1970年1月1日起,系统/控制器时间以毫秒的形式保持。我正在尝试使用 gmtime,但无法获得准确的结果。任何将此时间(毫秒)转换为实时小时:分钟:秒:天:月的示例都会有所帮助。
您可以使用civil_from_days
,该算法在Howard Hinnant的时间兼容低级日期算法中得到了详细的解释。 此函数计算自 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
这考虑了闰年。 它不需要闰秒。 您的嵌入式 Linux 系统/控制器不太可能这样做,因此尝试这样做是不正确的。
上述算法对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;
Fwiw,这是一个高级日期/时间库,利用 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';
}
gmtime()
不仅支持闰年,还考虑了闰秒,这就是为什么它tm_sec
字段的范围定义为 [0..60] 包括
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- gmtime() 函数是否考虑了闰年?