I get system time like this:
time_t t = time(0);
struct tm* now = localtime(&t);
TCHAR* tInfo = new TCHAR[256];
swprintf_s(tInfo
, 256
, _T("Current time: %i:%i:%i")
, now->tm_hour
, now->tm_min
, now->tm_sec);
And then show on screen:
std::cout << tInfo << std::endl;
But insted of Current time: 12:57:56 I got: 0x001967a8 on the screen. What I did wrong ?
You are trying to print a "wide" string. You need to use :
std::wcout << tInfo << std::endl;
The "narrow" version cout doesn't know about "wide" characters, so will just print the address, just like if you tried to print some other random pointer type.
Try:
std::wcout << tInfo << std::endl;
C++ shares its date/time functions with C. The tm structure is probably the easiest for a C++ programmer to work with - the following prints today's date:
#include <ctime>
#include <iostream>
using namespace std;
int main() {
time_t t = time(0); // get time now
struct tm * now = localtime( & t );
cout << (now->tm_year + 1900) << '-'
<< (now->tm_mon + 1) << '-'
<< now->tm_mday
<< endl;
}
Related
I have a backend process running 24*7 mostly built using C++ and I need to validate if an input date (in format YYYYMMDD) belongs in a set of next 5 business days. The input date is not a clear indicator of the current date so I am using the following function to get the current date and then calculating the next 5 business days from it.
const std::string& CurrentDateStr() {
static const std::string sDate = []() {
time_t currTime = time(NULL);
struct tm timeinfo;
localtime_r(&currTime, &timeinfo);
char buffer[16]="";
strftime(buffer, sizeof(buffer), "%Y%m%d", &timeinfo);
return std::string(buffer);
} ();
return sDate;
}
This function returns me the correct current date if the process was started today but if the process continues running till tomorrow then it will return me yesterday's date as current date due to which calculation of next 5 business days from current date goes for a toss.
Is this expected ? Is there some workaround for it or is there a better way to implement the requirement using standard C++
Your issue is the static variable. You should read up on that, because you're going to encounter it a lot. This is what the comments were trying to get you to do. You can fix your issue by just removing it:
const std::string& CurrentDateStr() {
time_t currTime = time(NULL);
struct tm timeinfo;
localtime_r(&currTime, &timeinfo);
char buffer[16]="";
strftime(buffer, sizeof(buffer), "%Y%m%d", &timeinfo);
return std::string(buffer);
}
For a more modern solution, as suggested in the comments as well, read up on chrono. Especially system_clock::now().
one way to do it using chrono:
#include <iostream>
#include <ctime>
#include <chrono>
#include <thread>
int main()
{
while (true)
{
theTime currentTime = time(nullptr);
tm* date = gmtime(¤tTime);
// Print the date and time
std::cout << "Current date and time: " << date->theDay << "/" << date->theMon + 1 << "/" << date->theYear + 1900;
std::cout << " " << date->theHour << ":" << date->theMmin << ":" << date->theSec << std::endl;
// Wait for 1 minute
std::this_thread::sleep_for(std::chrono::minutes(1));
}
}
OR Use the sleep method.
#include <iostream>
#include <ctime>
#include <unistd.h>
int main()
{
while (true)
{
time_t currentTime = time(nullptr);
tm* date = gmtime(¤tTime);
std::cout << "Current date and time: " << date->tm_mday << "/" << date->tm_mon + 1 << "/" << date->tm_year + 1900;
std::cout << " " << date->tm_hour << ":" << date->tm_min << std::endl;
// Wait for 1 minute (60 seconds)
sleep(60);
}
}
Is there a way to only compare time in C++?
For instance, given a array of predefined time (in string, e.g. "04:00", "07:00", "13:00") I want to be able to compare the current time with the range of time given in the array to see which fits.
I have tried strptime but I keep getting the undefined error. I have included time.h and stdio.h.
#include <stdio.h>
#include <ctime>
#include <time.h>
int main() {
//GET CURRENT TIME
time_t now = time(0);
tm *ltm = localtime(&now);
cout << "Time: "<< ltm->tm_hour << ":";
cout << ltm->tm_min << ":";
cout << ltm->tm_sec << endl;
//TRYING TO CONVERT THE TIME FROM STRING TO PROCEED FOR FURTHER COMPARISON
struct tm tm;
std::string s("04:00");
if (strptime(s.c_str(), "%H:%M", &tm)) { //error strptime is undefined
int d = tm.tm_mday,
m = tm.tm_mon + 1,
y = tm.tm_year + 1900;
std::cout << y << "-" << m << "-" << d << " "
<< tm.tm_hour << ":" << tm.tm_min;
}
//ATTEMPT TO DO TIME COMPARISON HERE
}
Am I missing out on any library?
Is there an easier/alternate way to do this?
Please guide me. Thanks
Timestamps from your example all have the same fixed format: two-digit hours, colon, two-digit minutes.
Which means they are perfectly subject to lexicographic comparison, via operator< on std::strings, std::strcmp, std::strncmp, std::memcmp, and so forth.
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
int main()
{
string NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
NowTime = nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
cout<< NowTime;
}
When I run the program, it display nothing, can someone help me? I am totally new in programming.
If you try
cout << nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
you'll see an integer, not anything resembling a time.
This is because it's the sum of five integers - the characters are promoted to integers, and then it's all added up.
The simplest fix is to not build a string at all but to output the parts individually:
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
Otherwise, you need to convert those numbers to strings:
NowTime = std::to_string(nowLocal.tm_hour) + ':' + std::to_string(nowLocal.tm_min) + ':' + std::to_string(nowLocal.tm_sec);
or, you can use a std::ostringstream, which works just like std::cout and other streams, but writes to a std::string:
std::ostringstream ss;
ss << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
NowTime = ss.str();
The line:
NowTime = nowLocal.tm_hour + ':' + nowLocal.tm_min + ':' + nowLocal.tm_sec;
is adding the hour, minute, and second to the numeric value of the colon symbol, since char is implicitly coerced to an int. That value is then being interpreted as a char in the string assignment operator.
Instead, you can simply output the values directly to cout. They will be formatted appropriately by cout's stream insertion operator <<.
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
int main()
{
string NowTime;
time_t now;
tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
return 0;
}
If you would instead want to store them in a string, read up about stringstreams. They have a similar syntax to cout and can make formatting strings much easier.
Instead of having to put the result in a variable, you could output it like this:
cout << nowLocal.tm_hour << ':' << nowLocal.tm_min << ':' << nowLocal.tm_sec;
Live Example
Also, if you want to keep the variable, do this:
NowTime = std::to_string(nowLocal.tm_hour) + ':' + std::to_string(nowLocal.tm_min) + ':' + std::to_string(nowLocal.tm_sec);
cout << NowTime;
Try this:
#include<iostream>
#include<ctime>
#include<string>
#include <sstream>
using namespace std;
int main()
{
string NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
stringstream s;
s<<nowLocal.tm_hour;
s<<":";
s<<nowLocal.tm_min;
s<<":";
s<<nowLocal.tm_sec;
NowTime = s.str();
cout<< NowTime;
}
You cannot cas directly from int to string and you need put values into stream and then to string.
What about using iostringstream to build the string you want?
#include<iostream>
#include<ctime>
#include<string>
#include <sstream>
using namespace std;
int main()
{
ostringstream NowTime;
time_t now;
struct tm nowLocal;
now=time(NULL); // get the time from the OS
nowLocal=*localtime(&now);
NowTime << nowLocal.tm_hour << ":" << nowLocal.tm_min << ":" << nowLocal.tm_sec;
cout<< NowTime.str() << endl;
}
Or for the purposes of your program you could simple use std::cout which also happens to be an output stream.
cout << nowLocal.tm_hour << ":" << nowLocal.tm_min << ":" << nowLocal.tm_sec << endl;
Since it looks like you're pre-c++11 and can't use std::to_string. Here's a C-like way of doing it, sticking to the includes you're currently using.
#include<iostream>
#include<ctime>
#include<string>
using namespace std;
#define STR_LEN 128
int main()
{
string nowTime;
time_t now;
struct tm nowLocal;
now = time( NULL ); // get the time from the OS
nowLocal = *localtime( &now );
char hour[ STR_LEN ], min[ STR_LEN ], sec[ STR_LEN ];
sprintf( hour, "%d", nowLocal.tm_hour );
sprintf( min, "%d", nowLocal.tm_min );
sprintf( sec, "%d", nowLocal.tm_sec );
nowTime = string( hour ) + ':' + string( min ) + ':' + string( sec );
cout << nowTime << endl;
}
How append system time to a string?
My answer is to build a convenience function.
If you really only need hour, minute, second, then you need not use the relatively slow localtime(). (on the other hand, if you do need more, I think you should prefer localtime_r() for the conversion).
For an embedded system several contracts back, I found this conversion to be a relatively slow function and chose to avoid it. The algorithms to handle leap days, centuries, etc. appear simple enough. I suspect I considered it slow simply because it calculates more than I needed in that application that was trying to do the conversion many times per second.
There exists a simpler (and probably still faster) approach involving modular arithmetic. It starts the same - with a time(0) (and thus I suspect what I am doing here is 'hidden' in the localtime_r() function). Side note 1 - on my older Dell running Ubuntu 15.10, time(0) is simply the fastest access to the wall clock, measuring about 6 or 7 ns 'typical' duration. Side note 2 - time_t may change someday. "The time_t Wikipedia article article sheds some light on this. The bottom line is that the type of time_t is not guaranteed in the C specification."
The code I currently use to conveniently generate a time stamp string:
std::string hhCmmCssGet(time_t tt = 0) // tt has default value
{
time_t now = ( tt ? tt : time(0) );
static time_t prev = 0;
static char hhmmss[] = "hh:mm:ss";
if (prev != now)
{
prev = now;
const int32_t CST = -6;
int64_t hr = ((now / 3600) % 24) + CST; // hr of day, CST offset
if (hr < 0) hr += 24;
uint64_t min = ((now / 60) % 60); // min of day
uint64_t sec = (now % 60); // sec of day
std::stringstream ss;
ss << std::dec
<< std::setfill('0') << std::setw(2) << hr << ":"
<< std::setfill('0') << std::setw(2) << min << ":"
<< std::setfill('0') << std::setw(2) << sec;
for (size_t i=0; i<8; i++) // transfer new value
hhmmss[i] = ss.str()[i]; // into static hhmmss
}
std::string retVal(hhmmss);
return(retVal);
}
The static items and "if (prev != now)" clause, allow this function to be invoked thousands of times per second ... with much reduced effort. The second, after all, only updates 1ce per second. And note that the std::stringstream stuff and modular arithmetic operations only run 1ce per second.
So I haven't seen here or anywhere else a way to get only the month hours and minutes using <ctime> or other library.
What I can do now is just get the full current date:
time_t now = time(0);
cout<<ctime(&now);
Any suggestions?
You can use the <ctime> standard library like this:
#include <ctime>
#include <iostream>
int main()
{
// get current time
std::time_t timer = std::time(0);
// convert to 'broken time'
std::tm bt = *std::localtime(&timer); // not thread safe
// extract month number from 'broken time' struct
std::cout << "month: " << (bt.tm_mon + 1) << '\n';
std::cout << "hours: " << (bt.tm_hour) << '\n';
std::cout << "mins : " << (bt.tm_min) << '\n';
}
The function std::localtime returns a pointer to an internal statc structure of type std::tm.
Because it returns a pointer to an internal struct it is best to copy it to a local version by dereferencing the pointer using *:
// copy what the returned pointer points to into `bt`.
std::tm bt = *std::localtime(&timer);
Since you are using ctime (C time), all C things should work. You could use strftime
char timestr[32];
strftime(timestr, sizeof(timestr), "%m:%H:%M", localtime(&now));
If boost is fine for you try this one :
boost::posix_time::to_simple_string(boost::posix_time::microsec_clock::local_time()).c_str()
try
std::put_time("%a %b %d %H:%M:%S %Y", &now);
I'm looking for a way to save the time in a HH::MM::SS fashion in C++. I saw here that they are many solutions and after a little research I opted for time and localtime. However, it seems like the localtime function is a little tricky, since it says:
All calls to localtime and gmtime use the same static structure, so
each call overwrites the results of the previous call.
The problem that this causes is shown in the next snippet of code:
#include <ctime>
#include <iostream>
using namespace std;
int main() {
time_t t1 = time(0); // get time now
struct tm * now = localtime( & t1 );
std::cout << t1 << std::endl;
sleep(2);
time_t t2 = time(0); // get time now
struct tm * now2 = localtime( & t2 );
std::cout << t2 << std::endl;
cout << (now->tm_year + 1900) << '-'
<< (now->tm_mon + 1) << '-'
<< now->tm_mday << ", "
<< now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec
<< endl;
cout << (now2->tm_year + 1900) << '-'
<< (now2->tm_mon + 1) << '-'
<< now2->tm_mday << ", "
<< now2->tm_hour << ":" << now2->tm_min << ":" << now2->tm_sec
<< endl;
}
A typical output for this is:
1320655946
1320655948
2011-11-7, 9:52:28
2011-11-7, 9:52:28
So as you can see, the time_t timestamps are correct, but the localtime messes everything up.
My question is: how do I convert a timestamp ot type time_t into a human-readable time?
If you are worried about reentrancy in localtime and gmtime, there is localtime_r and gmtime_r which can handle multiple calls.
When it comes to formatting the time to your liking, check the function strftime.
the localtime() call stores the results in an internal buffer.
Every time you call it you overwrite the buffer.
An alternative solution would be to make a copy of the buffer.
time_t t1 = time(0); // get time now
struct tm* now = localtime( & t1 ); // convert to local time
struct tm copy = *now; // make a local copy.
// ^^^ notice no star.
But note: The only time you should be converting to local time is when you display the value. At all other times you should just keep the time as UTC (for storage and manipulation). Since you are only converting the objects for display convert then print immediately and then things will not go wrong.
localtime has what is best considered a legacy interface. It can't be
used in multithreaded code, for example. In a multithreaded
environment, you can use localtime_r under Posix or localtime_s
under Windows. Otherwise, all you have to do is save the results:
tm then = *localtime( &t1 );
// ...
tm now = *localtime( &t2 );
It would probably be more idiomatic, however, to only call localtime
immediately before formatting the output, e.g.:
std::string
timestampToString( time_t timeAndDate )
{
char results[100];
if ( strftime( results, sizeof( results ), "%Y-%m-%d, %H:%M:%S",
localtime( &timeAndDate) ) == 0 ) {
assert( 0 );
}
return results;
}
and then writing:
std::cout << formatTime( t1 ) << std::endl;
(You could also create a more generic formatting function, which took
the format as an argument.)
You can run continuous clock using following code. It works nicely.
#include<iostream>
#include <Windows.h>
#include<ctime>
using namespace std;
void main() {
while(true) {
system("cls"); //to clear screen
time_t tim;
time(&tim);
cout << ctime(&tim);
Sleep(1);
}
}