C++ 从具有不同时区的字符串解析日期时间

c++ parse datetime from string with different timezone

本文关键字:字符串 日期 时间 时区 C++      更新时间:2023-10-16

如何从不同时区的字符串解析日期时间?我有简单的字符串中的日期和时间,例如 2011-01-15 04:01:00 ,它们来自纽约时区(东部:UTC -5/-4)。我在下面编写了代码,但它会自动将时区转换为我的本地时区。

是否可以在不增加 Boost 等 11 个库C++的情况下做到这一点,以免增加非常简单的操作的复杂性?如果没有,使用 Boost 的示例会很好。

我在Windows 8.1上使用Visual Studio 2013。

#include <ctime>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
    vector<string> datetimes{ "2011-01-15 04:01:00",
                              "2014-06-07 23:17:00",
                              "2015-11-29 14:55:00" };
    for (auto i : datetimes)
    {
        stringstream ss1(i);
        tm tm;
        ss1 >> get_time(&tm, "%Y-%m-%d %H:%M:%S");
        stringstream ss2;
        ss2 << put_time(&tm, "%c %Z");
        cout << ss2.str() << endl;
    }
}

输出:

01/15/11 04:01:00 Russia TZ 2 Daylight Time
06/07/14 23:17:00 Russia TZ 2 Daylight Time
11/29/15 14:55:00 Russia TZ 2 Daylight Time

但是我需要输出是这样的:

01/15/11 04:01:00 New York / Eastern (or whatever right name)
06/07/14 23:17:00 New York
11/29/15 14:55:00 New York

只需为此使用boost即可。认真地。下面是一些示例代码的样子:

using namespace boost::posix_time;
using namespace boost::gregorian;
//eastern timezone is utc-5
typedef boost::date_time::local_adjustor<ptime, -5, us_dst> us_eastern;
ptime t1(date(2001,Dec,31), hours(19)); //5 hours b/f midnight NY time
ptime t2 =  us_eastern::local_to_utc(t1); // t2 is now in utc
std::cout << to_simple_string(t1) << " in New York is " 
          << to_simple_string(t2) << " UTC time "
          << std::endl

示例代码取自 http://www.boost.org/doc/libs/1_42_0/doc/html/date_time/examples.html,并针对可读性和简洁性进行了调整,同时仍能回答问题。

无论您采用哪种解决方案,请确保永远不会手动减去时区转换或类似的东西。在某种程度上,您需要使用库。这些东西充满了陷阱,而且非常复杂,所以即使忘记有多少工作涉及或不涉及,如果你自己做,几乎肯定是不对的。

这是使用Howard Hinnant时区库的程序(免费,开源,将与VS-2013一起运行,确实需要一些安装)。

#include "tz.h"
#include <string>
#include <sstream>
#include <vector>
#include <iostream>
int main()
{
    using namespace std;
    using namespace date;
    vector<string> datetimes{ "2011-01-15 04:01:00",
                              "2014-06-07 23:17:00",
                              "2015-11-29 14:55:00" };
    zoned_seconds zt("America/New_York");
    for (auto const& i : datetimes)
    {
        stringstream ss1(i);
        local_seconds tm;
        ss1 >> parse("%F %T", tm);
        zt = tm;
        stringstream ss2;
        ss2 << format("%D %T %Z", zt);
        cout << ss2.str() << endl;
    }
}

输出:

01/15/11 04:01:00 EST
06/07/14 23:17:00 EDT
11/29/15 14:55:00 EST