将时间从大纪元转换为一年中的某一天?

时间:2017-07-06 18:39:49

标签: c++ time epoch

我有一个填充数据的文件,其中一列距离Epoch只有几秒钟。作为参考,示例值如下所示:

  

1498493536984926976

我需要将其转换为一年中的某一天。到目前为止我所拥有的是这段代码,它使用this reference将日期转换为普通可读结构,然后使用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);

但是,SegFaults行上的代码strftime!我不知道造成这种情况的原因。我尝试将buffer初始化为

char buffer[80];

以及各种其他声明但似乎没有任何效果。我还尝试完全抛弃缓冲区,只使用std::string;那也没有用。

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

任何帮助将不胜感激!

5 个答案:

答案 0 :(得分:4)

这些问题是您的问题:

char *buffer;

strftime (buffer,sizeof(buffer),"%j",&date);

您已经分配了char *,但它并没有指向任何内容。它只是一个随机值,因此您将一个狂野指针传递给strftime()。此外,sizeof(buffer)将是指针的大小(4或8个字节,具体取决于您的体系结构),而不是缓冲区应指向的数组的大小。

char * buffer更改为char buffer[32];或类似内容。

答案 1 :(得分:3)

基于它们应该是纪元时代的事实,你的时间戳是以纳秒为单位。

1498493536984926976s = 4.749E10 years

1498493536984926976ns = 47.49 years

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

答案 2 :(得分:2)

这是一个潜在的解决方案:

#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;
}

答案 3 :(得分:1)

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

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

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

你得到了

1499367157

这使1498493536984926976成为远期未来的日期。

答案 4 :(得分:1)

这里正在使用Howard Hinnant's free, open source date/time library

#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

注意:

  • 你没有指明,但我假设从纪元&#34;秒开始。意味着UTC。一旦开始调用localtime之类的内容,就会将计算机的本地时区偏移量带入计算中。我上面的代码保留了UTC中的所有内容。

  • 从文件中解析int后,格式化为一行,没有明确的转换因子。

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

&GT;

#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';
}

在后一种情况下,纳秒精度time_point被截断为time_point,精度为days。然后将截断的time_point转换为year_month_day对象,以便提取当前year(使用UTC)。最后从截断的time_point中减去该年的第一天,得到精度为chrono::duration的{​​{1}}。结果中添加了1,因为days指定Jan 1是第1天。

输出再次出现:

%j