Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 函数是否考虑闰年?_C++_Datetime_Embedded Linux_Microcontroller_Epoch - Fatal编程技术网

C++ 函数是否考虑闰年?

C++ 函数是否考虑闰年?,c++,datetime,embedded-linux,microcontroller,epoch,C++,Datetime,Embedded Linux,Microcontroller,Epoch,我在嵌入式linux上工作,自1970年1月1日起,系统/控制器时间一直以毫秒为单位。我试图使用gmtime,但无法获得准确的结果。任何将此时间(毫秒)转换为实时小时:分钟:秒:天:月的示例都将非常有用 不仅gmtime()支持闰年,它还占闰秒数,这就是为什么tm_sec字段的范围被定义为[0..60]包含在内。您可以使用霍华德·希南特的《从天开始的民事诉讼》。此函数计算自1970年1月1日起的天数,并将其转换为{y,m,d}字段。完成后,您只需从毫秒时间戳中减去天数,得到午夜后的毫秒数,然后将

我在嵌入式linux上工作,自1970年1月1日起,系统/控制器时间一直以毫秒为单位。我试图使用gmtime,但无法获得准确的结果。任何将此时间(毫秒)转换为实时小时:分钟:秒:天:月的示例都将非常有用

不仅
gmtime()
支持闰年,它还占闰秒数,这就是为什么
tm_sec
字段的范围被定义为[0..60]包含在内。

您可以使用霍华德·希南特的《从天开始的民事诉讼》。此函数计算自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';
}
这将闰年考虑在内。它不考虑闰秒。嵌入式linux系统/控制器也不太可能这样做,因此尝试这样做是不正确的

上述算法对
t
的有效性范围非常大:

-5877641-06-23 00:00:00.000 <= t <= 5880010-09-09 23:59:59.999
如果可以将
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
Fwiw,这里是一个利用C++11/14
库进行完全相同计算的程序,只是使用了更简洁的语法。要使用此库,您的std::lib必须支持

#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;
    cout << sys_time<milliseconds>(1490285505123ms) << '\n';
}
#包括“date.h”
#包括
int
main()
{
使用名称空间日期;
使用名称空间std;
使用名称空间std::chrono;

当然应该。一个例子,你说你得到的不准确的结果,以及产生这些结果的例子,将是有帮助的——事实上,如果你想回答你的问题,这是很重要的。(你知道
tm\mday
是基于1的,
tm mon
是基于0的,并且
tm_2;年
是基于1900的,对吗?)根据
C
标准,
gmtime()
不需要考虑闰秒,但允许考虑闰秒。此特性未指定。根据POSIX,
gmtime()
不计算闰秒,因为从1970-01-01T00:00:00 UTC开始,
time\u t
的计数中不包括闰秒。随后,很少(如果有的话)实现
gmtime()
计算闰秒(我不知道).闰年,是的。闰秒,不是。虽然你对
tm\u sec
的范围是正确的。在这方面,
struct tm
可以表示闰秒,只是
time\u t
不能。@HowardHinnant
time\u t
是否包括Linux和FreeBSD上的闰秒(可能还有其他版本)是可配置的。当它包含闰秒时,它们的
gmtime()
可以返回
tm_sec
60
。请参阅@hvd:Nice demo with
putenv(“TZ=right/UTC”)
,谢谢。
2000-03-01 00:00:00.000 <= t <= 2400-02-29 23:59:59.999
int32_t const era = 5;
#include "date.h"
#include <iostream>

int
main()
{
    using namespace date;
    using namespace std;
    using namespace std::chrono;
    cout << sys_time<milliseconds>(1490285505123ms) << '\n';
}