【问题标题】:How to properly convert a unix timestamp string to time_t in C++11?如何在 C++11 中正确地将 unix 时间戳字符串转换为 time_t?
【发布时间】:2015-08-30 20:44:00
【问题描述】:

假设我们有一个文本文件并从那里读取一些时间戳到一个局部变量“sTime”中:

std::string sTime = "1440966379" // this value has been read from a file.
std::time_t tTime = ? // this instance of std::time_t shall be assigned the above value.

如何将此字符串正确转换为 std::time 假设:

  1. 我们可能只使用 STL 方式(无提升)。
  2. 我们使用 C++11 标准
  3. 我们不知道我们使用的是哪种 CPU 架构/操作系统(它应该可以跨平台工作)
  4. 我们不能对 time_t 的内部定义方式做出任何(静态)假设。当然我们知道在大多数情况下它将是一个整数类型,可能是 32 位或 64 位长度,但是根据cppreference.com,time_t 的实际 typedef 没有指定。所以 atoi、atol、atol、strtoul ... 等至少在我们通过其他方式确定我们确实确实从这些可能的候选者中选出了正确的一个之前是没有问题的。

【问题讨论】:

  • 这个字符串是如何创建的? / 它代表什么?
  • 它是一个UNIX timestamp,计数自 1970 年 1 月星期四以来的秒数。它是在 linux bash 上使用命令“date +%s”创建的。它应该等于正确转换后 std::time_t 的内部值。
  • 所以我们可以假设std::time_t实际上包含一个UNIX时间戳?如果是这样,问题基本上是我如何解析std::time_t范围内的算术值
  • 不完全输入 sTime 是一个字符串,它不是算术值,而是表示算术值的字符序列。所以问题是我如何获取一个字符串值并将其正确转换为 std::time_t。编辑:根据您评论中的第一个问题:是的,我们可以假设它是一个 UNIX 时间戳,我们可能应用的任何转换都可能提供一些错误处理/异常机制。
  • 是的,很抱歉措辞不准确。由于您知道date +%s 的输出始终是一个整数(是吗?),您可以通过scanf 系列或使用unsigned long longistream::operator>> 将这些字符(ASCII?)解析为uintmax_t ,然后将其转换为time_t。我认为很难变得更通用,例如在uintmax_t小于64位但time_t大于uintmax_t的系统上(例如,因为time_tdouble);或者如果您需要更多 uintmax_t 的时间戳。

标签: c++ string time type-conversion


【解决方案1】:

这将使您的时间保持标准认可的格式:

需要#include <chrono>

std::string sTime = "1440966379"; // this value has been read from a file.

std::chrono::system_clock::time_point newtime(std::chrono::seconds(std::stoll(sTime)));
// this gets you out to a minimum of 35 bits. That leaves fixing the overflow in the 
// capable hands of Misters Spock and Scott. Trust me. They've had worse.

从那里你可以在time_points上做算术和比较。

将其转储回 POSIX 时间戳:

const std::chrono::system_clock::time_point epoch = std::chrono::system_clock::from_time_t(0);
// 0 is the same in both 32 and 64 bit time_t, so there is no possibility of overflow here
auto delta = newtime - epoch;
std::cout << std::chrono::duration_cast<std::chrono::seconds>(delta).count();

另一个 SO 问题涉及将格式化的字符串取出: How to convert std::chrono::time_point to std::tm without using time_t?

【讨论】:

  • 非常好的回答用户,您的建议效果很好,根据 cppreference 上的文档,它根据 std::time_t 的实际类型清除了所有假设。由于文档指出 chrono::seconds 采用 至少 35 位的参数,因此使用 stoll 获得的 long long 值似乎是安全的,即使在 32 位系统上,只要 chrono 可用.
猜你喜欢
  • 2016-09-27
  • 2013-01-16
  • 2017-07-29
  • 1970-01-01
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 2016-10-25
相关资源
最近更新 更多