将time_t转换为int64_t

时间:2012-10-04 22:15:40

标签: c++

我试图通过执行以下操作将time_t转换为in64_t。

time_t t = 1349388030;

我有一个API。

SomeObj.setValue(const int64_t)            // Sets the value of SomeObj to the passed argument
SomeObj.getValue(int64_t & value) const    // Returns the value

然后执行以下操作。

SomeObj.setValue(t)
int64_t tt;
SomeObj.getValue(tt)
assert (tt == t)                           // Fails where tt = 109726776

任何人都可以帮助正确的铸造程序吗?

编辑:

我的代码中的bug就像我使用set_value

一样

3 个答案:

答案 0 :(得分:3)

有3种情况需要担心从一种整数类型转换为另一种整数:

  1. 你从一个大整数转换为一个小整数。我有理由相信sizeof(int64_t) >= sizeof(time_t)所以这应该不是问题。
  2. 您将无符号类型转换为有符号类型,并且值超出了有符号类型的范围。由于1349388030小于2 ^ 31,因此不太可能。
  3. 您将签名类型转换为无符号类型,值为负数。这里不适用。
  4. 我不认为问题出在您的演员阵容中。

答案 1 :(得分:1)

我假设你所说的SomeObj并不关心时间是什么,它只是你需要存储时间的一些存储容器。我也假设在你的用例中,无论如何格式化你的时间  不需要是可移植的,并且存储的时间将始终用于生成它们的同一系统 。如果这些假设中的任何一个不成立,那么转换不适合您的问题(我在下面讨论一个更合适的解决方案,参考关于localtime()的讨论。)

要在time_t变量中存储int64_t值,当然sizeof(time_t)必须小于或等于sizeof(int64_t),因此您的代码需要对其进行断言检查。现在你不能只将一个time_t分配给一个int64_t(在大多数但不是所有系统上都可以正常工作),因为如果time_t是一个浮点类型,你很可能  在转换中失去精确度,当它转换回time_t时,它可能不是相同的值(尽管它可能“接近”正确的值)。关键是,对于可移植代码,您不能对time_t值的格式做任何假设。让我在此重申,即使下面的代码是可移植的,解决方案也不会生成本身可移植的时间值;即,如果您在一个系统上生成time_t值并且您的SomeObj将该值传输到另一个“系统”(即使在同一处理器上但由不同编译器编译)以便在另一个系统上进行解释,则另一个系统可能会或可能不会解释价值方式相同。为此,您需要将time_t转换为离散数字,可能通过localtime()localtime_r(),将 结构传输到其他系统,然后将其转换为 系统的time_t格式通过mktime()

在任何情况下,要以解释无关的方式将time_t值填充到uint64_t中,您需要将time_t值的位置读取为uint64_t。如果time_t没有uint64_t那么宽,你会读取额外的位,但这并不重要;这些位是“不关心”位。然后,要从uint64_t中读取time_t值,您需要将uint64_t位置的位读取为time_t。换句话说,你取的是地址 source变量,将其转换为目标类型的指针,然后取消引用它。如果类型的大小不匹配,您将在目标变量中读取额外的垃圾位,否则您将失去可能是垃圾位的位。以下是您在代码中执行此操作的方法......

#include <time.h>
#include <assert.h>

struct SomeClass
{
    int64_t i64;
    void setValue(const int64_t v) { i64 = v; }
    void getValue(int64_t& v) const { v = i64; }
};

#if 0 // Set to 1 for C style casting, or 0 for C++ style casting.

    int main()
    {
        assert (sizeof(int64_t) >= sizeof(time_t));
        // ...fundamental, otherwise nothing else has any hope of working

        SomeClass SomeObj;

        time_t t = 1349388030;
        int64_t i = *((int64_t*)&t);
        SomeObj.setValue(i);

        int64_t ii;
        time_t tt;
        SomeObj.getValue(ii);
        tt = *((time_t*)&ii);

        assert (tt == t);
    }

#else

    int main()
    {
        assert (sizeof(int64_t) >= sizeof(time_t));
        // ...fundamental, otherwise nothing else has any hope of working

        SomeClass SomeObj;

        time_t t = 1349388030;
        int64_t i = *reinterpret_cast<int64_t*>(&t);
        SomeObj.setValue(i);

        int64_t ii;
        time_t tt;
        SomeObj.getValue(ii);
        tt = *reinterpret_cast<time_t*>(&ii);

        assert (tt == t);
    }

#endif

答案 2 :(得分:0)

我发现您的代码没有问题。在某些平台time_t已经int64_t。我认为你的问题在其他地方。 SomeObj里面有什么?