How do I convert a string in seconds to time in C++ - c++

I have a string that stores the no of seconds since a process started. I need to convert this string with the no of seconds to time in C++. I need to subtract this time from the current time to get the time that this process started. I am confused and I do not know how to go about it. Please could someone help me out. I am a bit new to C++

Maybe you could try out Boost Time Library (http://www.boost.org/doc/libs/1_53_0/libs/timer/doc/index.html) or std::chrono if you're using newer compiler (as suggested below) and wish to stay within STL.

Something like that could work:
#include <chrono>
#include <string>
using namespace std::chrono;
std::string elapsed_time_in_s = "123456";
system_clock::time_point then = system_clock::now() -
std::chrono::seconds(std::stoll(elapsed_time_in_s));
time_t then_as_time_t = system_clock::to_time_t(then);

#include <sstream>
///
std::stringstream strs(seconds_string);
unsigned int tempTime=0;
if(!(strs >> tempTime))
//error
//calculate around with tempTime
if(!(strs << tempTime)
//error
if(!(strs >> seconds_string)
//error
//new string with the current time

You can use standard <time.h> routines (time, and gmtime or localtime).
For example:
void PrintProcessStartTimeAndDate(int numOfSeconds)
{
time_t rawtime;
struct tm* ptm;
time(&rawtime);
rawtime -= numOfSeconds;
ptm = gmtime(&rawtime); // or localtime(&rawtime);
printf("Process started at %.2d:%.2d:%.2d on %.2d/%.2d/%.2d\n",
ptm->tm_hour,ptm->tm_min,ptm->tm_sec,ptm->tm_mday,ptm->tm_mon+1,ptm->tm_year+1900);
}
Please note that gmtime and localtime routines are not thread-safe.
This fact is due to the pointer-to-static-structure that each one of them returns.

Related

Conversion of date from human-readable format to epoch fails

I'd like to create a program that converts the date of a specific human-readable format to epoch.
So far I have the following code the first part of which creates this human-readable format and the second one converts it to epoch.
#include <time.h>
#include <iostream>
#include <ctime>
#include <string>
#include <cstring>
using namespace std;
int main(int argc, char const *argv[])
{
time_t timeNow;
struct tm *ltm = NULL;
time(&timeNow);
ltm = localtime(&timeNow);
char buffer[100];
strftime(buffer, sizeof(buffer), "%c %Z", ltm);
cout << "human readable timestamp is " << buffer << endl;
std::tm tmNow;
memset(&tmNow, 0, sizeof(tmNow));
strptime(buffer, "%c %Z", &tmNow);
cout << "epoch timestamp is " << mktime(&tmNow) << endl;
return 0;
}
So the printouts I get are the following :
human readable timestamp is Thu Sep 16 10:23:06 2021 EEST
epoch timestamp is 1631780586
My time zone is EEST as one can see but the epoch one is wrong because it is one hour ahead. The correct should have been 1631776986. I assume I'm doing wrong something with the local time. I've found third-party libraries examples like boost or poco that do this conversion, but I'd prefer the above conversion to be done by using native C++.
Does anyone see what I'm missing?
The C timing/calendrical API is very difficult to use correctly (which is why C++ is moving away from it).
From the C standard:
The value of tm_isdst is positive if Daylight Saving Time is in effect, zero if Daylight Saving Time is not in effect, and negative if the information is not available.
Set tmNow.tm_isdst = -1; prior to the call to mktime.

How to get the current time and date C++ UTC time not local

I would like to know how I can get the UTC time or any other timezone (NOT just local time) in C++ Linux.
I would like to do something like: int Minutes = time.now(Minutes) to get and store the year, month, day, hour, minute and second at that exact time.
How I can do so?
I will need to repeat this process many time; I want to know the newest and best way to do so.
You are looking for the gmtime function in the time.h library, which give you UTC time. Here's an example:
#include <stdio.h> /* printf */
#include <time.h> /* time_t, struct tm, time, gmtime */
int main ()
{
time_t rawtime;
struct tm * ptm;
// Get number of seconds since 00:00 UTC Jan, 1, 1970 and store in rawtime
time ( &rawtime );
// UTC struct tm
ptm = gmtime ( &rawtime );
// print current time in a formatted way
printf ("UTC time: %2d:%02d\n", ptm->tm_hour, ptm->tm_min);
return 0;
}
Look at these sources:
https://www.cplusplus.com/reference/ctime/gmtime/
https://www.cplusplus.com/reference/ctime/time_t/
You can use system command in c++ if you want linux oriented solution
e.g.
#include <iostream>
#include <sstream> //for stringstream function to store date and time
using namespace std;
int main()
{
const char *date_now = "date -u"; //linux command to get UTC time is "date -u"
stringstream s;
s << system(date_now); //to store output of system("date_now") to s;
cout << s.str() << endl; //to print the string in s
return 0;
}
Check out "date --help" for more date and time related commands in linux terminal.

RFC3339 and in UTC/Zulu string to integer C++

I am writing a C+ application for an embedded ARM device.
My application receives a date and time string in format RFC3339 and in UTC/Zulu. For example "2020-12-14T23:18:13Z"
I need to get the time from this in seconds, compare it to the current time in seconds and take action if there is a difference between those times of greater than 8 seconds.
I've included a third party header file to help, date.h from here : https://howardhinnant.github.io/date/date.html
I have to say i'm still struggling to properly get the seconds from the date and time string as an integer and do comparisons. It is always zero in my case. This is what I have been trying for example so far:
#include <iostream>
#include <string>
#include <sstream>
#include "date.h"
int main()
{
std::string ts = "2020-11-14T22:14:16Z"; // Literal string to test at first
std::istringstream infile1{ts};
sys_seconds tps;
infile1 >> parse("%FT%T%Ez", tps);
auto stampSinceEpoch_s = tps.time_since_epoch();
// Get the current time
auto now = system_clock::now();
auto now_s = time_point_cast<seconds>(now);
auto nowSinceEpoch_s = now_s.time_since_epoch();
if ( (nowSinceEpoch_s .count() - stampSinceEpoch_s.count()) > 8)
{
// Time difference is greater than 8 seconds, take action
}
}
Any help is greatly appreciated.

How do I write a message timestamp to a log file?

I'm trying to create a logging file for my C++ program. My goal is to put two timestamps at two points of my program and print in a file the CPU time period between these two points. I'm doing this because I want to know which parts of my code are the most time consuming so I can make improvements (so there may be several chunks of code I want to measure). So far, I've made a function that, when called, prints a string that I pass as an argument, to a file:
#define LOGFILE "myprog.log"
void Log (std::string message){
std::ofstream ofs;
ofs.open(LOGFILE, std::ofstream::out | std::ios::app);
ofs << message << std::endl;
ofs.close();
}
However, I'm having difficulty figuring out how to print the CPU timestamp. Firstly, I don't know what time measurement format I should use (should I use the chrono or the time_t types?) I'm trying to print a time period so it would be helpful if there was a type for duration (I've tried chrono::duration but it seems to require C++11 support). Secondly, given I know what type to use, how do I print it to the file? Is there a way to cast that type to a string? Or can I pass it directly to my function and print it somehow?
This has troubled me a lot the last couple of days and I can't seem to figure it out, so any input would be really helpful. Thanks in advance!
Get a CPU Timestamp
You'll want to use std::chrono::system_clock to get this timestamp. Do not use std::chrono::steady_clock or std::chrono::high_resolution_clock, as those are for making high-precision timing measurements, and do not guarantee fidelity or accuracy to wall-clock time.
auto now = std::chrono::system_clock::now();
//now is a time_point object describing the instant it was recorded according to your system clock
Print this CPU Timestamp in a readable format
In C++20, this is pretty trivial.
std::string formatted_time = std::format("{0:%F_%T}", now);
ofs << formatted_time << ": " << message << std::endl;
%F is a substitute for %Y-%m-%D, which will output year-month-day in ISO format, i.e. 2018-10-09.
%T is the same for %H:%M:%S, which will output a time, i.e. 17:55:34.786
See the specification for std::format and std::formatter for more information about how to specify these parameters.
As of December 2020, no major compilers support the <format> library, yet, so as an alternative you can use fmt, which is a standalone implementation of the library.
Prior to C++20
Consider Howard Hinnant's date library, most of which is being incorporated into C++20 as a new part of the chrono library. The format function found in that library uses the same syntax as suggested above for the C++20 version, although without integration with std::format.
I'm usually use my implementation for such things.
#include <chrono>
#include <ctime>
// strftime format
#define LOGGER_PRETTY_TIME_FORMAT "%Y-%m-%d %H:%M:%S"
// printf format
#define LOGGER_PRETTY_MS_FORMAT ".%03d"
// convert current time to milliseconds since unix epoch
template <typename T>
static int to_ms(const std::chrono::time_point<T>& tp)
{
using namespace std::chrono;
auto dur = tp.time_since_epoch();
return static_cast<int>(duration_cast<milliseconds>(dur).count());
}
// format it in two parts: main part with date and time and part with milliseconds
static std::string pretty_time()
{
auto tp = std::chrono::system_clock::now();
std::time_t current_time = std::chrono::system_clock::to_time_t(tp);
// this function use static global pointer. so it is not thread safe solution
std::tm* time_info = std::localtime(&current_time);
char buffer[128];
int string_size = strftime(
buffer, sizeof(buffer),
LOGGER_PRETTY_TIME_FORMAT,
time_info
);
int ms = to_ms(tp) % 1000;
string_size += std::snprintf(
buffer + string_size, sizeof(buffer) - string_size,
LOGGER_PRETTY_MS_FORMAT, ms
);
return std::string(buffer, buffer + string_size);
}
It returns current time in format: 2018-09-23 21:58:52.642.
Yes it requires --std=c++11 or above.
For the record:
If C++20 features are not available, as in my case, you can use the following:
#include <ctime>
#include <iomanip>
#include <iostream>
using namespace std ;
time_t now = time(nullptr) ;
cout << put_time(localtime(&now), "%T") << endl ;
put_time is defined in iomanip library, look at https://en.cppreference.com/w/cpp/io/manip/put_time, and time_t and localtime are from the ctime, https://en.cppreference.com/w/cpp/chrono/c/ctime
If you want a more manual approach, this is what I've used before
char buffer[MAX_BUFFER_SIZE];
time_t t = time(NULL);
struct tm *lt = localtime(&t);
snprintf(buffer, MAX_BUFFER_SIZE, "%02d/%02d/%02d %02d:%02d:%02d", lt->tm_mon+1, lt->tm_mday, lt->tm_year%100, lt->tm_hour, lt->tm_min, lt->tm_sec);
Then just output buffer, which now contains string representation of time, to your file.

How to display real time in c++

Can some one tell me how do i display real time in c++. what i mean is that while the program is running you can see the seconds and or minutes counting down like a real clock hanging on the wall
this is what I have:
int main ()
{
time_t rawtime; //creates and object of the built in time function
struct tm * timeinfo; //no idea what this do
time ( &rawtime ); //gets the time from the computer
timeinfo = localtime ( &rawtime ); //store that time here
//it displays current date and time except time is frozen and not real time
cout<< "Current local time and date: "<<asctime (timeinfo)<< endl;
system("pause");
return 0;
}
Not in C++ (in C/Win32) but works.
#include <stdio.h>
#include <windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
SYSTEMTIME stime; //structure to store system time (in usual time format)
FILETIME ltime; //structure to store local time (local time in 64 bits)
FILETIME ftTimeStamp;
char TimeStamp[256];//to store TimeStamp information
while (true){
////Prepare data needed to output the time stamp:
GetSystemTimeAsFileTime(&ftTimeStamp); // Gets the current system time
FileTimeToLocalFileTime (&ftTimeStamp,&ltime);//convert in local time and store in ltime
FileTimeToSystemTime(&ltime,&stime);//convert in system time and store in stime
sprintf(TimeStamp, "%d:%d:%d, %d.%d.%d \r",stime.wHour,stime.wMinute,stime.wSecond, stime.wDay,stime.wMonth,stime.wYear);
printf(TimeStamp);
Sleep(1000);
}
system("pause");
return 0;
}
Some basic C++ will come in a long way: www.cplusplus.com
int main ()
{
time_t rawtime; //creates and object of the built in time function
struct tm * timeinfo; //no idea what this do
while (true)
{
time( &rawtime ); //gets the time from the computer
timeinfo = localtime( &rawtime ); //store that time here
//it displays current date and time except time is frozen and not real time
cout<< "Current local time and date: "<<asctime (timeinfo)<< endl;
sleep(1000); //1 second sleep
}
system("pause");
return 0;
}
Try this:
while (true) {
std::cout << '\r'; // return to the beginning of the line
getAndPrintTime(); // do what you do now, but don't write endl
}
Assuming that you want to keep overwriting the same place in the terminal, two simple things to use are '\r' for carriage return, and '\b' for backspace (if you want to back up a character rather than a whole line).
Add a system("cls");
Like this:
time_t rawtime;
struct tm* timeinfo;
while(true)
{
system("cls");
time(&rawtime);
timeinfo=localtime(&rawtime);
cout<<"Time : "<<asctime(timeinfo);
Sleep(1000);
}
The standard C++ language did not have any notion of time till the latest C++11 standard published in 2011, and rarely implemented. On Linux, you could consider using GCC 4.6 or 4.7 which implements most of it.
(older C++03 gives you <ctime>)
Otherwise, time is given by operating system specific libraries and system calls (such as gettimeofday and clock_gettime on Linux and Posix)
If you have a fully C++11 conformant implementation of the latest C++ standard (which may be unlikely, in particular on Windows), you could use the <chrono> standard header.
Below is the a function within a program of mine that displays the current day of week, time (hh:mm) and date (dd/mm/yyy). When I used the SYSTEMTIME struct, I realized the time displayed was four hours too fast, so I resorted to this method. Hope this helps. Intended for Windows users...
void time()
{
cout << "The current date is: ";
system("date/t");
cout << "The current time is: ";
system("time/t");
cout << "Time zone: ";
system("tzutil /g");
cout << endl;
}
NOTE: This works by querying your system for the date, time, and timezone. Most seasoned programmers do not recommend utilizing the system() tool, but that is ultimately up to you.