获得iso 8601时间戳c ++之前和之后的设定时间

pyC*_*hon 3 c++ c++11

如果有一个标准的ISO 8601时间戳,是否可以通过简单的方法从20分钟前获得时间戳,并在原始时间戳后20分钟获得另一个时间戳?

举个例子

 2010-01-25 18:02:00
Run Code Online (Sandbox Code Playgroud)

我想要一个或两个函数返回, 2010-01-25 17:48:002010-01-25 18:22:00

我放弃的解决方案相当繁琐,我s.substr(14,2)用来获取分钟并s.substr(12,2)获得小时数,将小时和分钟字符串转换为int并减去或添加带有条件的分钟值,如果它超过60或低于0.有更好/更简单的方法吗?

ken*_*ytm 9

你可以:

  1. 将字符串转换为struct tm 使用std::get_time.
  2. 修改struct tm(无需考虑范围).
  3. 规范化struct tm 使用mktime.
  4. 打印struct tm 使用std::put_time

#include <ctime>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

std::string increase_minutes(const std::string& input, int delta) {
    struct tm tm;
    constexpr auto format = "%Y-%m-%d %T";

    std::istringstream iss (input);
    iss >> std::get_time(&tm, format);
    tm.tm_min += delta;
    mktime(&tm);

    std::ostringstream oss;
    oss << std::put_time(&tm, format);
    return oss.str();
}


int main() {
    auto s = "2012-12-31 23:59:00";
    std::cout << increase_minutes(s, 20) << std::endl;
    std::cout << increase_minutes(s, -20) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

请注意,std::get_timestd::put_time以g ++/++的libstdc缺席.您可能需要使用C函数解析字符串sscanf或者strptime,使用打印字符串strftime.另请参阅C++日期和时间.


编辑:如果我们想通过泛型进行更改std::chrono::duration,我们最好std::chrono::time_point直接操作.我们可以通过struct tm两步转换创建一个time_point :time_point↔time_t↔structtm,如下图所示:

#include <ctime>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <chrono>

template <typename R, typename P>
std::string increase_iso_time(const std::string& input, 
                              const std::chrono::duration<R, P>& duration) {
    struct tm tm;
    constexpr auto format = "%Y-%m-%d %T";

    std::istringstream iss (input);
    iss >> std::get_time(&tm, format);
    auto time = mktime(&tm);
    auto tp = std::chrono::system_clock::from_time_t(time);

    tp += duration;

    time = std::chrono::system_clock::to_time_t(tp);
    tm = *localtime(&time);
    std::ostringstream oss;
    oss << std::put_time(&tm, format);
    return oss.str();
}

int main() {
    auto s = "2012-12-31 23:59:00";
    std::cout << increase_iso_time(s, std::chrono::minutes(20)) << std::endl;
    std::cout << increase_iso_time(s, - std::chrono::hours(4)
                                      - std::chrono::minutes(20)) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)