I have char start_time[40] = "2020-04-01 12:00:00"; How can I convert the char array to timestamp in C++ without using strptime?
You can try this:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
int main(void) {
const char T[] = "2020-04-01 12:00:00";
time_t result = 0;
int year = 0, month = 0, day = 0, hour = 0, min = 0,sec=0;
if (sscanf(T, "%4d-%2d-%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min,&sec) == 6) {
struct tm test_time = {0};
test_time.tm_year = year - 1900; /* years since 1900 */
test_time.tm_mon = month - 1;
test_time.tm_mday = day;
test_time.tm_hour = hour;
test_time.tm_min = min;
test_time.tm_sec = sec;
if ((result = mktime(&test_time)) == (time_t)-1) {
fprintf(stderr, "Cannot convert time to time_t\n");
return EXIT_FAILURE;
}
std::cout << result << '\n' ;
puts(ctime(&result));
struct tm *t_start = localtime(&result);
char date_time[30];
strftime( date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", t_start );
std::cout << date_time << '\n' ;
return EXIT_SUCCESS;
}
else {
fprintf(stderr, "The input was not a valid time format\n");
return EXIT_FAILURE;
}
}
Related
It is about to collect logs of event viewer from the remote machine.I have tried Event Logging api so far. Though,It works well by reading logs from the localhost,was failed to read from remote machine.
HANDLE OpenEventLogA(
[in] LPCSTR lpUNCServerName,
[in] LPCSTR lpSourceName
);
Using this,I have tried to open event logs by mentioning ipaddress of remote machine in the place of UNCServerName.But,it doesn't work.Below is the code,I've tried so far.
#include <windows.h>
#include <stdio.h>
#include <bits/stdc++.h>
#include <winbase.h>
#include<string.h>
#include <iostream>
#include<vector>
#define BUFFER_SIZE 1024*200
#define MAX_TIMESTAMP_LEN 23 + 1
#define MAX_WORD_LEN 1000
using namespace std;
struct SearchRecord {
string type;
string time;
string source;
string eid;
};
void FillEventRecordDetails(std::vector<SearchRecord*> *searchRecordResult)
{
HANDLE h;
int i=1,j=0;
EVENTLOGRECORD *pevlr;
BYTE bBuffer[BUFFER_SIZE];
DWORD dwRead, dwNeeded, dwRecord,dwThisRecord;
// Open the Application event log.
h = OpenEventLog(//ip address//,
"Application");
if (h == NULL)
{
cout<<GetLastError();
}
cout<<"HANDLE:"<<h;
pevlr = (EVENTLOGRECORD *) &bBuffer;
GetOldestEventLogRecord(h, &dwThisRecord);
cout<<"Record Number:"<<dwThisRecord;
GetNumberOfEventLogRecords(h, &dwRecord);
cout<<"\n New:"<<dwRecord+dwThisRecord;
while (ReadEventLog(h, EVENTLOG_SEEK_READ|
EVENTLOG_FORWARDS_READ ,
dwThisRecord,
pevlr,
BUFFER_SIZE,
&dwRead,
&dwNeeded))
{
while (dwRead > 0 )
{
//TYPE
string type;
switch(pevlr->EventType)
{
case EVENTLOG_ERROR_TYPE:
type = "ERROR";
break;
case EVENTLOG_WARNING_TYPE:
type = "WARNING";
break;
case EVENTLOG_INFORMATION_TYPE:
type = "INFORMATION";
break;
case EVENTLOG_AUDIT_SUCCESS:
type = "AUDIT_SUCCESS";
break;
case EVENTLOG_AUDIT_FAILURE:
type = "AUDIT_FAILURE";
break;
default:
type = "Unknown";
break;
}
//TIME
DWORD Time = ((PEVENTLOGRECORD)pevlr)->TimeGenerated ;
ULONGLONG ullTimeStamp = 0;
ULONGLONG SecsTo1970 = 116444736000000000;
SYSTEMTIME st;
FILETIME ft, ftLocal;
ullTimeStamp = Int32x32To64(Time, 10000000) + SecsTo1970;
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
FileTimeToLocalFileTime(&ft, &ftLocal);
FileTimeToSystemTime(&ftLocal, &st);
ostringstream mon1 , day1 ,year1,hour1,min1,sec1,mil1;
mon1 << st.wMonth ;day1 << st.wDay ;year1 << st.wYear ;hour1 << st.wHour ;min1 << st.wMinute ;sec1 << st.wSecond ;mil1 <<st.wMilliseconds;
string mon = mon1.str();string day = day1.str();string year = year1.str();string hour = hour1.str();string min = min1.str();string sec = sec1.str();
string mil=mil1.str();
string time = day+"-"+mon+"-"+year+" "+hour+":"+min+":"+sec+":"+mil;
int id = ((PEVENTLOGRECORD)pevlr)->EventID & 0xFFFF;
ostringstream temp;
temp << id;
string eid = temp.str();
string source = (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));
SearchRecord *pRecord = new SearchRecord();
pRecord->type = type;
pRecord->time = time;
pRecord->eid = eid;
pRecord->source = source;
searchRecordResult->push_back(pRecord);
cout<<i;
cout<<" Type:"<<type;
cout<<" Time:"<<time;
cout<<" Event Id:"<<id;
cout<<" source:"<<source;
cout<<"\n";
i++;
dwRead -= pevlr->Length;
pevlr = (EVENTLOGRECORD *)
((LPBYTE) pevlr + pevlr->Length);
}
dwThisRecord+=i;
pevlr = (EVENTLOGRECORD *) &bBuffer;
}
CloseEventLog(h);
}
int main()
{
vector<SearchRecord*> searchRecordResult ;
FillEventRecordDetails(&searchRecordResult);
}
Is there any way to read logs from remote machine using c++ code?
Thanks in advance.
Hello i compliled my c++ program and if i start the .exe i got a error
Image from the error
This is my source(main.cpp):
#include <iostream>
#include <string>
#include <Windows.h>
#include <dos.h>
#include <stdio.h>
#include <fstream>
#include <ctime>
// using
using namespace std;
bool fexists(const char *filename);
int main() {
try {
HANDLE h;
string cClipboard = "";
CreateDirectory("C:\\Program Files\\Clipboard Logger", NULL);
if (!fexists("C:\\Program Files\\Clipboard Logger\\log.txt")) {
FILE *fp;
fp = fopen("C:\\Program Files\\Clipboard Logger\\log.txt", "w");
fclose(fp);
}
while (true) {
if (!OpenClipboard(0)) {
Sleep(2000);
continue;
}
h = GetClipboardData(CF_TEXT);
CloseClipboard();
if ((char *)h == cClipboard) {
Sleep(2000);
continue;
}
cClipboard = (char *)h;
time_t t = time(0);
struct tm * now = localtime(&t);
FILE *fp;
fp = fopen("C:\\Program Files\\Clipboard Logger\\log.txt", "a");
int day = now->tm_mday;
int month = now->tm_mon + 1;
int year = now->tm_year + 1900;
int sec = now->tm_sec;
int min = now->tm_min;
int hour = now->tm_hour;
char logLine[sizeof((char *)h) + 64];
sprintf(logLine, "%d.%d.%d %d.%d.%d %s\n", hour, min, sec, day, month, year, (char *)h);
fprintf(fp, (char *)logLine);
fclose(fp);
cout << (char *)logLine << endl;
Sleep(2000);
}
getchar();
return 0;
} catch (...) {
}
}
bool fexists(const char *filename) {
ifstream ifile(filename);
if (ifile)
return true;
return false;
}
iam new in c++ and i dont know how to fix it, because if i debug the program all works fine but with the exe it doesnt work.
If I have this string:
2011-10-08T07:07:09Z
is it possible to get a time_t from it? If so, how can this be done?
Yes, it is. First, convert it to a broken down time with strptime(3). This gives you a struct tm, which is the structure type for a broken down time.
From there, you can convert to a time_t with mktime(3).
Here's an example:
#define _XOPEN_SOURCE
#include <time.h>
#include <stdio.h>
#include <string.h>
int main(void) {
const char *date_example = "2011-10-08T07:07:09Z";
struct tm broken_down;
memset(&broken_down, 0, sizeof(broken_down));
strptime(date_example, "%Y-%m-%dT%H:%M:%SZ", &broken_down);
broken_down.tm_isdst = 0; // Indicates that DST is not in effect
time_t epoch_time = mktime(&broken_down);
// Note: this is platform dependent
printf("Epoch time: %lld\n", (long long) epoch_time);
return 0;
}
Use sscanf() to tear apart the time. The trick is somehow determine the difference between local and universal time so code may call mktime() - which uses assumes struct tm is local time..
#include <time.h>
#include <stdio.h>
int Get_TZ_delta(const struct tm *tmptr) {
// Make local copy
struct tm tm = *tmptr;
time_t t = mktime(&tm);
struct tm utc_tm = *gmtime(&t);
time_t t2 = mktime(&utc_tm);
return (int) difftime(t, t2);
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
struct tm tm = { 0 };
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &tm.tm_year, &tm.tm_mon,
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &sentinel) != 6) {
return -1;
}
// struct tm uses offset from 1900 and January is month 0
tm.tm_year -= 1900;
tm.tm_mon--;
// Convert tm from UCT to local standard time
tm.tm_isdst = 0;
tm.tm_sec += Get_TZ_delta(&tm);
time_t t = mktime(&tm); // mktime() assumes tm is local
// test code
{
printf("UTC `%s`\n", ts);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", (long long) mktime(&tm));
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
Output
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T17:07:52 CDT
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T02:07:09 CDT
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1969-12-31T18:00:00 CST
Unix 0
Another approach works should code know that time_t is the number of seconds since Jan 1, 1970 0:00:00. Uses sscanf() to parse the string, calculate the number of days, and then return the number of seconds.
#include <time.h>
#include <stdio.h>
#define MARCH 3
#define DaysPer400Years (400*365LL + 97)
#define DaysPer100Years (100*365LL + 24)
#define DaysPer4Years (4*365LL + 1)
#define DaysPer1Year 365LL
#define DayNumber1970Jan1 719469LL
long long DayNumber(int year, int Month, int Day, long epoch) {
long long dn = Day;
long long y = year;
y += Month / 12;
Month %= 12;
while (Month < MARCH) {
Month += 12;
y--;
}
// And then a miracle occurs.
dn += ((Month - MARCH) * (7832 / 4) + (140 / 4)) >> (8 - 2);
dn += (y / 400) * DaysPer400Years;
y %= 400;
dn += (y / 100) * DaysPer100Years;
y %= 100;
dn += (y / 4) * DaysPer4Years;
y %= 4;
dn += y * DaysPer1Year;
return dn - epoch;
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
int y,m,d,H,M,S;
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &y, &m,
&d, &H, &M, &S, &sentinel) != 6) {
return -1;
}
long long t = DayNumber(y, m, d, DayNumber1970Jan1);
t = t*24L*60*60 + 3600L*H + 60*M + S;
// test code
{
printf("UTC `%s`\n", ts);
time_t tt = t;
struct tm tm = *gmtime(&tt);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", t);
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
Output
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T22:07:52
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T07:07:09
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1970-01-01T00:00:00
Unix 0
I am using below method to validate Date.
How to format month in string ?
bool CDateTime :: IsValidDate(char* pcDate) //pcDate = 25-Jul-2012 15:08:23
{
bool bVal = true;
int iRet = 0;
struct tm tmNewTime;
iRet = sscanf_s(pcDate, "%d-%d-%d %d:%d:%d", &tmNewTime.tm_mon, &tmNewTime.tm_mday, &tmNewTime.tm_year, &tmNewTime.tm_hour, &tmNewTime.tm_min, &tmNewTime.tm_sec);
if (iRet == -1)
bVal = false;
if (bVal == true)
{
tmNewTime.tm_year -= 1900;
tmNewTime.tm_mon -= 1;
bVal = IsValidTm(&tmNewTime);
}
return bVal;
}
Using strptime:
#include <time.h>
char *str = "25-Jul-2012 15:08:23";
struct tm tm;
if (strptime (str, "%d-%b-%Y %H:%M:%S", &tm) == NULL) {
/* Bad format !! */
}
The C++11 way of doing this is:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <chrono>
int main()
{
auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now);
std::cout << "Now is " << std::put_time(std::localtime(&now_c), "%d-%b-%Y %H:%M:%S") << '\n';
}
Note: The stream I/O manipulator std::put_time is not implemented fully in all compilers yet. GCC 4.7.1 does not have it for example.
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"
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
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
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.
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;
}
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.