从 UTC 日期字符串转换为 Unix 时间戳并返回
Convert from UTC date string to Unix timestamp and back
如何将 UTC 中的“2021-11-15 12:10” 之类的字符串转换为 Unix 时间戳?
然后将两个小时添加到时间戳(如 timestamp += 60*60*2
)。
然后将生成的时间戳转换为相同格式的字符串 UTC?
使用 <chrono>
、<ctime>
或库,并不重要。
您可以使用 I/O 操纵器 std::get_time
and std::put_time
。
示例:
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
int main() {
std::istringstream in("2021-11-15 12:10"); // put the date in an istringstream
std::tm t{};
t.tm_isdst = -1; // let std::mktime try to figure out if DST is in effect
in >> std::get_time(&t, "%Y-%m-%d %H:%M"); // extract it into a std::tm
std::time_t timestamp = std::mktime(&t); // get epoch
timestamp += 2 * 60 *60; // add 2 hours
std::tm utc = *std::gmtime(×tamp); // make a UTC std::tm
std::tm lt = *std::localtime(×tamp); // make a localtime std::tm
// print the results:
std::cout << std::put_time(&utc, "%Y-%m-%d %H:%M") << '\n'
<< std::put_time(<, "%Y-%m-%d %H:%M") << '\n';
}
随着最近对输入字符串表示 UTC date/time 的编辑,问题变得既简单又复杂。
- 更简单,因为没有时区、夏令时和政治家的复杂问题。
- 更复杂的是没有可移植的 C 或 C++ 解决方案(在 C++20 之前),尽管有平台相关的解决方案。
此答案提出了一种在 C++20 中新增的可移植解决方案。但是,如果您没有 C++20,则存在一个适用于 C++11/14/17 和所有平台的 free, open-source, header-only solution that previews this part of C++20。
#include <chrono>
#include <fmt>
#include <iostream>
#include <sstream>
std::string
test(std::string ts)
{
using namespace std::chrono;
std::istringstream in{std::move(ts)};
sys_seconds tp;
in >> parse("%F %H:%M", tp);
return std::format("{:%F %H:%M}", tp + 2h);
}
int
main()
{
std::cout << test("2021-11-15 12:10") << '\n';
}
以上是C++20的解决方案。类型 sys_seconds
是一个 Unix 时间戳。它计算自 1970-01-01 00:00:00 UTC 以来的秒数,不包括闰秒。如果你想要它的秒数,那就是 tp.time_since_epoch().count()
.
一个人简单地解析它,加上两个小时,然后格式化它。从不考虑本地时区,因此不存在极端情况。这总是有效的。
例如本地时区为“America/New_York”,输入字符串为“2021-11-07 00:10”,则输出字符串为“2021-11-07 02:10”。但是,如果此输入字符串与当前接受的答案一起使用,则输出字符串将减少一个小时:“2021-11-07 01:10”。
要使用 free, open-source, header-only solution:
- 将
#include <fmt>
替换为#include "date/date.h"
- 添加
using namespace date;
- 将最后一行改为
return format("%F %H:%M", tp + 2h);
如何将 UTC 中的“2021-11-15 12:10” 之类的字符串转换为 Unix 时间戳?
然后将两个小时添加到时间戳(如 timestamp += 60*60*2
)。
然后将生成的时间戳转换为相同格式的字符串 UTC?
使用 <chrono>
、<ctime>
或库,并不重要。
您可以使用 I/O 操纵器 std::get_time
and std::put_time
。
示例:
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
int main() {
std::istringstream in("2021-11-15 12:10"); // put the date in an istringstream
std::tm t{};
t.tm_isdst = -1; // let std::mktime try to figure out if DST is in effect
in >> std::get_time(&t, "%Y-%m-%d %H:%M"); // extract it into a std::tm
std::time_t timestamp = std::mktime(&t); // get epoch
timestamp += 2 * 60 *60; // add 2 hours
std::tm utc = *std::gmtime(×tamp); // make a UTC std::tm
std::tm lt = *std::localtime(×tamp); // make a localtime std::tm
// print the results:
std::cout << std::put_time(&utc, "%Y-%m-%d %H:%M") << '\n'
<< std::put_time(<, "%Y-%m-%d %H:%M") << '\n';
}
随着最近对输入字符串表示 UTC date/time 的编辑,问题变得既简单又复杂。
- 更简单,因为没有时区、夏令时和政治家的复杂问题。
- 更复杂的是没有可移植的 C 或 C++ 解决方案(在 C++20 之前),尽管有平台相关的解决方案。
此答案提出了一种在 C++20 中新增的可移植解决方案。但是,如果您没有 C++20,则存在一个适用于 C++11/14/17 和所有平台的 free, open-source, header-only solution that previews this part of C++20。
#include <chrono>
#include <fmt>
#include <iostream>
#include <sstream>
std::string
test(std::string ts)
{
using namespace std::chrono;
std::istringstream in{std::move(ts)};
sys_seconds tp;
in >> parse("%F %H:%M", tp);
return std::format("{:%F %H:%M}", tp + 2h);
}
int
main()
{
std::cout << test("2021-11-15 12:10") << '\n';
}
以上是C++20的解决方案。类型 sys_seconds
是一个 Unix 时间戳。它计算自 1970-01-01 00:00:00 UTC 以来的秒数,不包括闰秒。如果你想要它的秒数,那就是 tp.time_since_epoch().count()
.
一个人简单地解析它,加上两个小时,然后格式化它。从不考虑本地时区,因此不存在极端情况。这总是有效的。
例如本地时区为“America/New_York”,输入字符串为“2021-11-07 00:10”,则输出字符串为“2021-11-07 02:10”。但是,如果此输入字符串与当前接受的答案一起使用,则输出字符串将减少一个小时:“2021-11-07 01:10”。
要使用 free, open-source, header-only solution:
- 将
#include <fmt>
替换为#include "date/date.h"
- 添加
using namespace date;
- 将最后一行改为
return format("%F %H:%M", tp + 2h);