C++ 将时间(秒)从历元转换为一年中的某一天?

C++ 将时间(秒)从历元转换为一年中的某一天?,c++,time,epoch,C++,Time,Epoch,我有一个装满数据的文件,其中一列是从纪元算起的秒数。作为参考,示例值如下所示: 149849353698926976 我需要把它转换成一年中的一天。到目前为止,我掌握的是这段代码,它用于将日期转换为正常可读的结构,然后使用strftime从结构中提取一年中的某一天: time_t rawtime = stol(exploded_line[2]); std::cout << rawtime << std::endl; struct tm date; date = *loc

我有一个装满数据的文件,其中一列是从纪元算起的秒数。作为参考,示例值如下所示:

149849353698926976

我需要把它转换成一年中的一天。到目前为止,我掌握的是这段代码,它用于将日期转换为正常可读的结构,然后使用strftime从结构中提取一年中的某一天:

time_t rawtime = stol(exploded_line[2]);
std::cout << rawtime << std::endl;
struct tm date; 
date = *localtime( &rawtime );
char *buffer;
std::cout << 2 << std::endl;
strftime (buffer,sizeof(buffer),"%j",&date);
和其他各种声明,但似乎没有任何效果。我还尝试完全抛弃缓冲区,只使用
std::string
;这也没用

而且,我并不偏爱这种方法。如果其他人有更好的方法从一个大纪元获得一年中的某一天,我将完全实现它


任何帮助都将不胜感激

您的实际问题是
localtime(&rawtime)
无法转换
rawtime
。当函数失败时,它返回一个空指针。取消引用该指针并尝试复制其值会导致segfault

最可能的问题是你的价值太大了。如果你这样做

std::time_t t = std::time(nullptr);
std::cout << t << std::endl;

这使得
14984935363984926976
成为遥远未来的一个日期。

这些都是你的问题:

char *buffer;

strftime (buffer,sizeof(buffer),"%j",&date);
您已经分配了一个
字符*
,但它没有指向任何东西。它只是一个随机值,所以您将一个野生指针传递到
strftime()
。另外,
sizeof(buffer)
将是指针的大小(4或8字节,取决于您的体系结构),而不是缓冲区应该指向的数组的大小


char*buffer
更改为
char buffer[32]或类似的东西。

这里有一个潜在的解决方案:

#include <string>
#include <iostream>
#include <ctime>

int main() {
  // Original value is a 64-bit unsigned integer representing the time in nanoseconds
  long long rawtime = 1498493536984926976LL;

  std::cout << rawtime << std::endl;

  // To convert from nanoseconds to seconds divide by a billion
  time_t epochtime = rawtime / 1000000000LL;
  std::cout << epochtime << std::endl;

  struct tm date;
  date = *std::localtime(&epochtime);

  // Uses a fixed-length buffer for `strtftime`
  char buffer[256];
  std::cout << 2 << std::endl;
  strftime(buffer,sizeof(buffer),"%j",&date);

  std::cout << buffer << std::endl;
}
#包括
#包括
#包括
int main(){
//原始值是以纳秒为单位表示时间的64位无符号整数
长拉长时间=149849363694926976LL;

std::cout基于它们应该是大纪元的事实,您的时间戳以纳秒为单位

14984935363984926976s=4.749E10年

149849336984926976ns=47.49年

除非你的时间戳真的是340亿年后的未来,否则你应该先将它们转换为秒,然后再将它们发送到
localtime
,以获得
struct tm
,,这里它使用:

注:

  • 您没有指定,但我假设“从纪元算起的秒数”是指UTC。一旦您开始调用
    localtime
    ,您就将计算机的本地时区偏移量带入计算中。我上面的代码将所有内容保留为UTC

  • 一旦从文件中解析了
    int
    ,格式就是一行,没有显式的转换因子

  • 如果您需要将一年中的某一天作为
    int
    ,而不是流式输出,这也很容易实现:

>



老实说,我可能会去找一个日期-时间库,并将其包含在文件中,因为这是一个我不想要的头疼问题。@Jhecht我希望哈哈。这不是我的数据集,它是一个多月前被占用的。我只有历元数据。我很确定有人已经创建了历元-日期库。显示
localtime
实际上是e问题。虽然不确定原因,但我认为这会有所帮助。
char*buffer
是一个未初始化的缓冲区,因此当您
strftime
达到该值时,它将崩溃。
char buffer[80]
至少给你一些可以使用的东西。看看格式化之类的东西。该值也是以纳秒为单位的,而不是秒,它超出了
时间
的范围。尝试除以100000000。当前时间现在是
1499366981
时间
是一个32位带符号的数字。不过请注意前缀。它是64位-位高精度时间值。@tadman抱歉,我的代码块出现了错误。注释是否仍然相关,如果是,您可以详细说明一下吗?1499367157是十亿的多少倍?它与您假设的在遥远的将来的值非常接近。@tadman op说
149849336984926976
是秒。如果这是真的,那么它就是秒在遥远的未来。因此,要么OP误读了数据实际代表的内容,要么日期在遥远的未来。这一时间要么是2017年6月26日,要么是47485371817年8月30日。更合理的解决方案,正如询问者所证实的,是它是纳秒。在太阳膨胀到大约8bi后,没有人会预约百万年。OP已经说他们把
buffer
改成了
char buffer[80]
,但这没有用。char*buffer;
是一个骗局。我写答案时他没有这么说。但他说“我的调试器把它钉在strftime行上了”。是的,他做了。这一行已经出现在Q中,需要记录评论。@LightnessRacesinOrbit很好。在那里添加了一点上下文。现在很好:)我现在把它标记为正确的,因为它肯定让我更接近正确的答案(返回一个17世纪的数字,这是有意义的,因为日期应该在5月左右).Thank@Ics根据Wolframalpha的说法。@Ics谢谢,我应该检查一下,哈哈。这仍然与数据采集时的情况一致。47.49显然接近年中;)
char *buffer;

strftime (buffer,sizeof(buffer),"%j",&date);
#include <string>
#include <iostream>
#include <ctime>

int main() {
  // Original value is a 64-bit unsigned integer representing the time in nanoseconds
  long long rawtime = 1498493536984926976LL;

  std::cout << rawtime << std::endl;

  // To convert from nanoseconds to seconds divide by a billion
  time_t epochtime = rawtime / 1000000000LL;
  std::cout << epochtime << std::endl;

  struct tm date;
  date = *std::localtime(&epochtime);

  // Uses a fixed-length buffer for `strtftime`
  char buffer[256];
  std::cout << 2 << std::endl;
  strftime(buffer,sizeof(buffer),"%j",&date);

  std::cout << buffer << std::endl;
}
#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    std::istringstream file{"1498493536984926976"};
    std::int64_t i;
    file >> i;
    std::cout << format("%j\n", sys_time<nanoseconds>{nanoseconds{i}});
}
177
#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std::chrono;
    using namespace date;
    std::istringstream file{"1498493536984926976"};
    std::int64_t i;
    file >> i;
    auto sd = floor<days>(sys_time<nanoseconds>{nanoseconds{i}});
    auto y = year_month_day{sd}.year();
    int doy = (sd - sys_days{y/jan/1}).count() + 1;
    std::cout << doy << '\n';
}
177