0

I have a code that works fine on windows, and I have to make it compatible with Linux. Can anyone help me configure the following code snippet to windows?

    MongoDB* db = MongoDB::getInstance();
    mongocxx::pipeline p{};
    struct tm tm;
    strptime(fromdate.c_str(), "%Y-%m-%d %H %M %S", &tm); //this line gives me some errors 
    std::time_t tt = std::mktime(&tm);

The error that I'm getting `error C3861: 'strptime': identifier not found

I tried to use the code in http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD but it also gives some error because it says some header files such as #include <sys/cdefs.h> , #include "namespace.h" are missing

can anyone tell me how to include those header files in the project or any other way of fixing this issue Thank you in advance

  • Possible duplicate https://stackoverflow.com/questions/321849/strptime-equivalent-on-windows – Galik Mar 25 '21 at 08:06
  • @Galik I tried it but I get some errors when using http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD as header. I wan to know the way of fixing missing headers – Tharindu Balasuriya Mar 25 '21 at 08:18
  • strptime is a POSIX function not included in current windows SDK. You need implement it by yourself or use other one's port. – Zongru Zhan Mar 25 '21 at 08:21

1 Answers1

2

If you can't get the BSD version of strptime working, you could try Howard Hinnant's date.h

Or you could create a simple conversion function for this particular format yourself. Example:

#include <cstdio>
#include <ctime>
#include <cerrno>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>

std::tm to_tm(const std::string_view& date) {
    std::tm t{};

    if(std::sscanf(date.data(), "%d-%d-%d %d %d %d",
        &t.tm_year,
        &t.tm_mon,
        &t.tm_mday,
        &t.tm_hour,
        &t.tm_min,
        &t.tm_sec
    ) != 6)
        throw std::runtime_error("Invalid date format: " + std::string(date));

    t.tm_year -= 1900;
    --t.tm_mon;
    t.tm_isdst = -1;  // guess if DST should be in effect when calling mktime
    errno = 0;
    std::mktime(&t);
    
    return t;
}

int main() {
    std::string fromdate = "2021-03-25 08 23 56";

    std::tm x = to_tm(fromdate);

    std::cout << std::asctime(&x) << '\n'; // Thu Mar 25 08:23:56 2021
}

Or, a non-throwing version that returns std::time_t directly:

#include <system_error> // added to be able to set an error code

std::time_t to_time_t(const std::string_view& date) {
    std::tm t{};

    if(std::sscanf(date.data(), "%d-%d-%d %d %d %d",
        &t.tm_year,
        &t.tm_mon,
        &t.tm_mday,
        &t.tm_hour,
        &t.tm_min,
        &t.tm_sec
    ) != 6) {
        // EOVERFLOW (std::errc::value_too_large)
        // This is what Posix versions of mktime() uses to signal that -1 does
        // not mean one second before epoch, but that there was an error.
        errno = static_cast<int>(std::errc::value_too_large);
        return -1;
    }
    t.tm_year -= 1900;
    --t.tm_mon;
    t.tm_isdst = -1;  // guess if DST should be in effect when calling mktime
    
    errno = 0;
    return std::mktime(&t);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108