【问题标题】:How to get the time in milliseconds since epoch time from boost::posix_time::ptime如何从 boost::posix_time::ptime 获取自纪元时间以来的毫秒数
【发布时间】:2011-10-24 13:46:36
【问题描述】:

我看到一些other answers on SO 建议我们可以通过从“其他”时间中减去纪元时间来获得以毫秒为单位的纪元时间,但是当我尝试它时它不起作用:

ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.000");

long diff = (other-epoch).total_milliseconds();

在这个阶段差异是 -1349172576,它应该是一个正数,因为“其他”时间是 2011 年。有人知道可能导致这种情况的原因吗?获取自纪元以来的毫秒数的正确方法是什么?

另外,我尝试从毫秒构造一个 ptime 对象:

ptime result = from_time_t(diff);

然后结果变为:“1927-Apr-01 13:50:24”,它应该是“2011-Aug-09 17:27:00.000”。这里有什么问题?

更新:

好的,所以我的错误源于我有 2 个程序,一个是 C#(8 字节/64 位长)和一个 C++(4 字节/32 位长);无论如何,这里没有描述这种交互。

但是,当我使用 long long 时,该值为正,但生成的日期(构造 from_time_t)仍然不正确:“2012-Oct-02 10:09:36”。

【问题讨论】:

  • 你的平台上long的大小是多少?
  • 您的机器有多长?以毫秒为单位的 40 年大约是 2^40 毫秒。尝试谷歌搜索log(40+years/1+millisecond)/log(2)
  • 啊... Windows,long 是 4 个字节,我应该使用 long long。我的程序有 2 个组件,一个 C# 和一个 C++; C# 中的 long 是 8 个字节,但在 C++ 中只有 4 个字节,所以有点搞砸了。
  • @Lirik : from_time_t 采用time_t,这通常是long 的类型定义。所以你回到了第一方。你真正想要是什么类型的?
  • 我想获取long long 并将其转换为ptime

标签: c++ datetime date boost time


【解决方案1】:

假设您在long 小于64 位的平台上。

假设它是 32 位 - 在这种情况下,long 的最大值是 2147483648。但是,it's been ~1312000000000 milliseconds since epoch,所以long 显然不足以容纳这个值,因此您会看到溢出。

我会这样做:

ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.000");

time_duration const diff = other - epoch;
long long ms = diff.total_seconds();
ms *= 1000LL;
ms += diff.fractional_seconds() / 1000000L; // 1000L if you didn't build datetime
                                            // with nanosecond resolution

从指定的毫秒数创建ptime 也有同样的问题——ptime 根据long 工作,而你有一个long long——所以你基本上需要做相反的事情:

// given long long ms
time_duration t = seconds(static_cast<long>(ms / 1000LL));
if (ms % 1000LL)
    t += milliseconds(static_cast<long>(ms % 1000LL));

【讨论】:

  • 是的,我有一个 C# 和一个 C++ 程序,它们应该从纪元开始传输时间,我刚刚意识到 C# long 是 8 个字节,而 C++ long 是 4 个字节。话虽如此,long long 实际上是一个正数,但是当我尝试通过在结果上调用from_time_t 来构造ptime 时,我再次得到一个不正确的日期:“2012-Oct-02 10:09:36” .
  • @Lirik :您的问题仅表明您想要自纪元以来的毫秒数 - time_t 来自哪里?即,您最终真正想要的数据类型是什么?
  • 我希望能够在毫秒 (long long) 和 ptime 之间来回切换。以毫秒为单位的时间与纪元有偏移。
  • 我如何知道我构建的日期时间是否具有纳秒分辨率?默认是如何构建的,即我什么都没改,默认分辨率是多少?
  • @Lirik : Quoting the docs -- "默认情况下,posix_time 系统在内部使用单个 64 位整数来提供微秒级别的分辨率。作为替代方案,64 位的组合整数和 32 位整数(96 位分辨率)可用于提供纳秒级分辨率。"
【解决方案2】:

ildjarn 出色解决方案的简化版本:

ptime epoch = time_from_string("1970-01-01 00:00:00.000");
ptime other = time_from_string("2011-08-09 17:27:00.001");

time_duration const diff = other - epoch;
long long ms = diff.total_milliseconds();

这与它是否以纳秒分辨率构建无关。

【讨论】:

    【解决方案3】:

    你可以试试:

    ptime other = time_from_string("2011-08-09 17:27:00.000");
    time_t posix_time = (other - ptime(min_date_time)).total_seconds();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-02
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 2013-08-19
      相关资源
      最近更新 更多