Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.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++ 转换自";起的秒数;1904年1月1日午夜”;添加到日期时间字符串_C++_C++11_Time - Fatal编程技术网

C++ 转换自";起的秒数;1904年1月1日午夜”;添加到日期时间字符串

C++ 转换自";起的秒数;1904年1月1日午夜”;添加到日期时间字符串,c++,c++11,time,C++,C++11,Time,在某些多媒体元数据中,可能存在以秒为单位的日期时间 UTC时间1904年1月1日午夜 我知道,日期时间函数通常是在C/C++标准库中的1970-1—午夜,至少在Visual C++中,在C/C++ +Win32 API中有一个函数,将“自194-1-1午夜”的秒转换为日期时间字符串,如“HH:MM,SS,DD,YYYY”或其他格式字符串,或结构类似于“StuttTM”? 解决方案#1: int main() { SYSTEMTIME systm; memset(&syst

在某些多媒体元数据中,可能存在以秒为单位的日期时间 UTC时间1904年1月1日午夜

我知道,日期时间函数通常是在C/C++标准库中的1970-1—午夜,至少在Visual C++中,在C/C++ +Win32 API中有一个函数,将“自194-1-1午夜”的秒转换为日期时间字符串,如“HH:MM,SS,DD,YYYY”或其他格式字符串,或结构类似于“StuttTM”? 解决方案#1:

int main()
{
    SYSTEMTIME systm;
    memset(&systm, 0, sizeof(systm));

    systm.wYear = 1904;
    systm.wMonth = 1;
    systm.wDay = 1;

    FILETIME filetm;
    if (SystemTimeToFileTime(&systm, &filetm) == FALSE){
        printf("Failed to convert system time to file-time.\n");
        return 0;
    }

    ULARGE_INTEGER nanoSeconds;
    nanoSeconds.HighPart = filetm.dwHighDateTime;
    nanoSeconds.LowPart = filetm.dwLowDateTime;

    nanoSeconds.QuadPart += 3600ULL * 10000000; // add 1hour based on 1904/1/1 midnight

    filetm.dwHighDateTime = nanoSeconds.HighPart;
    filetm.dwLowDateTime = nanoSeconds.LowPart;

    if (FileTimeToSystemTime(&filetm, &systm) == FALSE){
        printf("Failed to convert file-time to system time.\n");
        return 0;
    }

    printf("New system time by adding 1 hour: %d-%02d-%02d %02d:%02d:%02d.%03d\n", 
        systm.wYear, systm.wMonth, systm.wDay, 
        systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);

    return 0;
}
输出是

New system time by adding 1 hour: 1904-01-01 01:00:00.000
解决方案#2:

int main()
{
    SYSTEMTIME systm;
    memset(&systm, 0, sizeof(systm));

    systm.wYear = 1904;
    systm.wMonth = 1;
    systm.wDay = 1;

    FILETIME filetm;
    if (SystemTimeToFileTime(&systm, &filetm) == FALSE){
        printf("Failed to convert system time to file-time.\n");
        return 0;
    }

    ULARGE_INTEGER nanoSeconds;
    nanoSeconds.HighPart = filetm.dwHighDateTime;
    nanoSeconds.LowPart = filetm.dwLowDateTime;

    nanoSeconds.QuadPart += 3600ULL * 10000000; // add 1hour based on 1904/1/1 midnight

    filetm.dwHighDateTime = nanoSeconds.HighPart;
    filetm.dwLowDateTime = nanoSeconds.LowPart;

    if (FileTimeToSystemTime(&filetm, &systm) == FALSE){
        printf("Failed to convert file-time to system time.\n");
        return 0;
    }

    printf("New system time by adding 1 hour: %d-%02d-%02d %02d:%02d:%02d.%03d\n", 
        systm.wYear, systm.wMonth, systm.wDay, 
        systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);

    return 0;
}

使用@Howard Hinnant的date.h,它也可以解决这个问题,请参阅他提供的示例代码

这里的时间问题实际上要求您为它编写自己的代码。1900年是一个例外,因为它可以被4整除,但仍然不是闰年,因此从1904年开始,你可以避免这个特殊的例外,并使用从1904年开始的每四年有1461天的事实。

这将是一个很好的使用时间:

更新 上述代码将通过以下方式移植到C++20(当其装运时):

  • #包括“date/date.h”
    更改为
    #包括
  • 使用名称空间日期更改
    转换为
  • %T%m.%d,%Y“
    更改为
    “{:%T%m.%d,%Y}”

您可以使用系统中的任何可用电子表格应用程序轻松计算这两个时间戳之间的秒差(假设两者都是UTC时间)从
1/1/1904
1/1/1970
的秒差是
2082844800秒。
因此,从unix时间戳到时间的转换函数包括将
2082844800
添加到从任何时间函数接收到的unix时间戳中。若要将时间中的时间戳传递回unix时间戳,请从时间刻度中减去该固定值。请注意,该数字不适合
签名int
,因此您必须使用64位数字来正确管理所有这些时间戳。更糟糕的是,如果你想使用纳秒的分辨率


我猜不出使用那个奇怪的历元时间戳的原因,但为了说明这种差异的实际应用,在互联网上有一个时间戳,它使用的历元接近那个历元,那就是NTP(网络时间协议)时间戳,这是基于1/1/1900时代的,它有一个解决方案:<代码> 1/2 **32秒。< /代码>,在代码< 232页> <代码> >,对于这个协议的规范,请参阅< /P>不,在C或C++库中没有这样的函数。但这似乎并不复杂。日期数学很久以前就已经是一个解决了的问题。我们可以很容易地计算出一年中有多少天,每天有多少秒,还有多少毫秒。基于此,这是一个相当简单的计算。我很确定(我希望)这类问题是每门中级计算机编程课程的例行作业。你可以使用c++11标准中的std::chrono在1904-1-1午夜创建一个时间点,然后再加上几秒钟,它需要有多好?例如,它需要处理闰秒吗?Unix时间戳是有符号的,所以32位值可以追溯到1901年12月。另一方面,Win32 API使用的日期格式可以追溯到1601年。请参阅。@KarstenKoop:unix时代从1970-01-01开始。并非所有系统都使用
int32\t
。在64位系统上,通常使用
int64\u t
。我尝试运行您的示例代码,但在使用VS2015的环境中编译失败,错误消息如下:错误C2127:“date::nanyear”:非法初始化非常量表达式的“constexpr”实体VS2015在
constexpr
上非常弱。尝试将
constexpr
转换为
offset
const
类型。这使函数的效率降低了一点。我相信升级到VS2017会解决这个问题。啊,一个
constexpr
潜入date.h。谢谢你的错误报告!我马上把它修好。同时,如果在date.h中更改
constexpr year nanyear{-32768}到<代码>常数数据年{-32768},这将使它在VS2015上运行。是的,在将
constexpr自动偏移
更改为
auto offset
,并将
constexpr year nanyear{-32768}
更改为
constedata year nanyear{-32768}
后,它在VS2015中工作!伟大的我已经修复了github回购协议。
#include "date/date.h"
#include <cstdint>
#include <iostream>
#include <string>

std::string
convert(std::int64_t seconds_since_1904)
{
    using namespace date;
    using namespace std::chrono;
    constexpr auto offset = sys_days{January/1/1970} - sys_days{January/1/1904};
    return format("%T %m.%d, %Y", sys_seconds{seconds{seconds_since_1904}} - offset);
}

int
main()
{
    std::cout << convert(3'606'124'378) << '\n';
}
13:12:58 04.09, 2018