53

I have a string variable containing time in hh:mm:ss format. How to convert it into time_t type? eg: string time_details = "16:35:12"

Also, how to compare two variables containing time so as to decide which is the earliest? eg : string curr_time = "18:35:21" string user_time = "22:45:31"

R11G
  • 1,941
  • 8
  • 26
  • 37
  • 2
    Note that time_t encodes the number of seconds since midnight, 1 January 1970 this be careful using it to encode just the time without the date. – Rob K Jun 26 '12 at 18:18

5 Answers5

73

With C++11 you can now do

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);

see std::get_time and strftime for reference

v2blz
  • 761
  • 5
  • 7
  • 2
    I think it's worth to mention that std::get_time is **available in GCC from version 5**, you need then `#include ` – MBI Jan 17 '17 at 07:52
  • 1
    shouldn't mktime take &tm? – Behrooz Karjoo Feb 08 '17 at 18:59
  • 2
    `std::get_time` has also some bugs under VS2013 e.g. here http://stackoverflow.com/questions/32019209/is-this-a-bug-in-stdget-time and here http://stackoverflow.com/questions/35041344/trying-to-use-stdget-time-to-parse-yymmdd-and-failing – Wakan Tanka Feb 16 '17 at 07:53
  • 1
    Be warned if working with time zones that mktime expects tm to be a time appropriate to the local time zone. – Joseph Van Riper Sep 06 '19 at 17:08
  • 1
    When used on dates, `mktime` was returning -1 for me. Fixed it by changing the first line to `struct std::tm tm = {0};`, – Rumák Mar 24 '21 at 08:48
65

You can use strptime(3) to parse the time, and then mktime(3) to convert it to a 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
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
18

This should work:

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);

Modify as needed.

Mahmoud Al-Qudsi
  • 28,357
  • 12
  • 85
  • 125
0

Here's the complete C implementation with date & time.

        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;
        }
omar Enayet
  • 61
  • 1
  • 3
0

use strptime.

struct tm tm;
memset(&tm, 0, sizeof(tm));
char *res = strptime(strtime.c_str(), format.c_str(), &tm);
if (res == nullptr) {
    // err process
}
ti = mktime(&tm);

Must init tm, and check the return value.

selfboot
  • 1,490
  • 18
  • 23