如何将包含时间的字符串变量转换为 c++ 中的 time_t 类型?

Posted

技术标签:

【中文标题】如何将包含时间的字符串变量转换为 c++ 中的 time_t 类型?【英文标题】:How to convert a string variable containing time to time_t type in c++? 【发布时间】:2012-06-28 02:59:30 【问题描述】:

我有一个字符串变量,其中包含 hh:mm:ss 格式的时间。如何将其转换为 time_t 类型?例如:字符串 time_details = "16:35:12"

另外,如何比较两个包含时间的变量,以确定哪个是最早的? 例如:字符串 curr_time = "18:35:21" 字符串 user_time = "22:45:31"

【问题讨论】:

请注意,time_t 编码自 1970 年 1 月 1 日午夜以来的秒数,请小心使用它来编码不带日期的时间。 【参考方案1】:

使用 C++11,您现在可以做到

struct std::tm tm;
std::istringstream ss("16:35:12");
ss >> std::get_time(&tm, "%H:%M:%S"); // or just %T in this case
std::time_t time = mktime(&tm);

请参阅std::get_time 和strftime 以供参考

【讨论】:

我认为值得一提的是 std::get_time 在 GCC 版本 5 中可用,那么你需要 #include <iomanip> mktime 不应该带 &tm 吗? std::get_time 在 VS2013 下也有一些错误,例如这里***.com/questions/32019209/… 和这里***.com/questions/35041344/… 如果使用 mktime 期望 tm 是适合本地时区的时间的时区,请注意。 在日期上使用时,mktime 为我返回 -1。通过将第一行更改为struct std::tm tm = 0; 来修复它,【参考方案2】:

您可以使用strptime(3)解析时间,然后mktime(3)将其转换为time_t

const char *time_details = "16:35:12";
struct tm tm;
strptime(time_details, "%H:%M:%S", &tm);
time_t t = mktime(&tm);  // t is now your desired time_t

【讨论】:

strptime 是 Linux 特有的,我相信。 @KyleStrand:它是 POSIX.1-2001(以及 SUSv2)的一部分。没错,它不是标准的 C 或 C++,但它不仅仅是 Linux。 谢谢。我应该考虑检查一下。 注意日期仍然是 1970 年 1 月 1 日,而不是您运行程序的那一天【参考方案3】:

这应该可行:

int hh, mm, ss;
struct tm when = 0;

sscanf_s(date, "%d:%d:%d", &hh, &mm, &ss);


when.tm_hour = hh;
when.tm_min = mm;
when.tm_sec = ss;

time_t converted;
converted = mktime(&when);

根据需要修改。

【讨论】:

请注意,sscanf_s 不是处理这个问题的 C++ 方式,而是 C 方式(尽管在这种情况下它可以工作并且相当安全,所以没有反对意见)。使用 std::stringstream>> 会更符合 C++ 的习惯。 @peachykeen 是的,这是正确的。如果你发布 C++ 版本,我会支持 :) 这段代码可以获取时间,但是date (yyyy-MM-dd)呢? @LeiYang 我在问题的任何地方都没有看到日期。 @LeiYang sscanf(forceNextImportAfter, "%d-%d-%d %d:%d:%d", &year, &month, &day,&hour,&minute,&second)【参考方案4】:

这是带有日期和时间的完整 C 实现。

        enum DateTimeFormat 
            YearMonthDayDash, // "YYYY-MM-DD hh:mm::ss"
            MonthDayYearDash, // "MM-DD-YYYY hh:mm::ss"
            DayMonthYearDash  // "DD-MM-YYYY hh:mm::ss"
        ;

        //Uses specific datetime format and returns the Linux epoch time.
        //Returns 0 on error
        static time_t ParseUnixTimeFromDateTimeString(const std::wstring& date, DateTimeFormat dateTimeFormat)
        
            int YY, MM, DD, hh, mm, ss;
            struct tm when =  0 ;
            int res;

            if (dateTimeFormat == DateTimeFormat::YearMonthDayDash) 
                res = swscanf_s(date.c_str(), L"%d-%d-%d %d:%d:%d", &YY, &MM, &DD, &hh, &mm, &ss);
            
            else if (dateTimeFormat == DateTimeFormat::MonthDayYearDash) 
                res = swscanf_s(date.c_str(), L"%d-%d-%d %d:%d:%d", &MM, &DD, &YY, &hh, &mm, &ss);
            
            else if (dateTimeFormat == DateTimeFormat::DayMonthYearDash) 
                res = swscanf_s(date.c_str(), L"%d-%d-%d %d:%d:%d", &DD, &MM, &YY, &hh, &mm, &ss);
            
            //In case datetime was in bad format, returns 0.
            if (res == EOF || res == 0) 
                return 0;
            

            when.tm_year = YY - 1900; //Years from 1900
            when.tm_mon = MM - 1; //0-based
            when.tm_mday = DD; //1 based

            when.tm_hour = hh;
            when.tm_min = mm;
            when.tm_sec = ss;

            //Make sure the daylight savings is same as current timezone.
            time_t now = time(0);
            when.tm_isdst = std::localtime(&now)->tm_isdst;

            //Convert the tm struct to the Linux epoch
            time_t converted;
            converted = mktime(&when);

            return converted;
        

【讨论】:

以上是关于如何将包含时间的字符串变量转换为 c++ 中的 time_t 类型?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中将变量名转换为字符串

尝试返回 c++ 输入文件的大小,但在将 char 变量转换为字符串时收到错误

如何将包含时区的字符串转换为日期时间 sql server

如何将 SINGLE char 转换为系统字符串 C++?

Getopt :: Long将包含空格的字符串转换为变量

如何将 C++ 或 C 中的字符串转换为整数数组?