c++ if the current time = given time - c++

i need help i have a simple program but it wont work
here is my code
i want to check if the current system time equals to the given time and do something
#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>
#pragma warning(disable : 4996)
const std::string currentDateTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d.%X", &tstruct);
return buf;
}
int main() {
while (true)
{
currentDateTime();
char * currtimetochar = strcpy(new char[currentDateTime().length() + 1], currentDateTime().c_str());
//std::cout << idokes << std::endl;
if (currtimetochar == "2020-08-31.19:29:59")//given time date for example {
std::cout << "success!" << std::endl;
// do something more
}
}
getchar();
}

A better approach would be to encode a given time string to a LOCALTIME or SYSTEMTIME and compare that instead of comparing strings whose format would change in different locales. SYSTEMTIME is better for "absolute time comparisons" (it's in UTC) although using LOCALTIME may be sufficient to meet your needs.

Related

Trying to convert postgres time stamp string to c++ time stamp

I have PostgreSQL timestamp string:
2020-07-06 09:30:00.646533
I'm trying to convert it to timeval struct, I tried using this answer, but I'm getting this output:
Thu Jan 1 00:33:40 1970
This is my code:
#include <iostream>
int main()
{
std::string ss("2020-07-06 09:30:00.646533");
auto t = atoll(ss.c_str());
time_t time = atoi(ss.c_str());
std::cout << asctime(gmtime(&time));
return 0;
}
When running with debugger, I see that this line
auto t = atoll(ss.c_str());
isn't working/set time with values.
How can i fix it?
atoll and atoi simply parse integers of various sizes from a string. They aren't great functions to use in general as they have no way of indicating that they have failed to parse the string. std::stoi and friends are the better functions to use. However in this case we don't have a number we have a date string so std::stoi won't work either (but it can at least tell you it didn't work).
c++20 comes with much better date support, until then Howard Hinnant's date library provides the same functionality:
#include "date.h"
#include <iostream>
#include <sstream>
#include <chrono>
int main()
{
std::stringstream ss("2020-07-06 09:30:00.646533");
// convert string to date time
std::chrono::system_clock::time_point time;
ss >> date::parse("%F %T", time);
if (!ss) {
std::cout << "invalid date\n";
return 1;
}
// get the amount of time since the epoch, assumes std::chrono::system_clock uses the same epoch as timeval
auto sinceEpoch = time.time_since_epoch();
// get the whole number of seconds
auto seconds = date::floor<std::chrono::seconds>(sinceEpoch);
// get the remaining microseconds
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(sinceEpoch - seconds);
std::cout << seconds.count() << ", " << microseconds.count() << "\n";
return 0;
}
If you must re-invent the wheel you can do it using the pre c++20 standard library:
#include <iostream>
#include <sstream>
#include <chrono>
#include <iomanip>
int main()
{
std::stringstream ss("2020-07-06 09:30:00.646533");
std::tm tm;
// convert string to date time
std::chrono::system_clock::time_point time;
double fraction;
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S") >> fraction;
if (!ss) {
std::cout << "invalid date\n";
return 1;
}
time_t seconds = mktime(&tm);
int64_t microseconds = fraction * 1'000'000;
std::cout << seconds << ", " << microseconds << "\n";
return 0;
}
Note that the microseconds should really be parsed as an integer not a double but you have to be careful to handle strings with different numbers of digits after the decimal point and with leading zeros.
you can use like this:
#include<ctime>
#include<iotream>
int main()
{
std::string ss = "2020-07-06 09:30:00.646533";
auto i = ss.find_first_of('.');
std::string line(ss.begin()+(i+1),ss.end());
std::tm tm = {};
tm.tm_isdst = -1; // <- to set not to use day lghite saveing.
strptime(ss.c_str(), "%F %H:%M:%S", &tm); //<-enter the data to tm
start.tv_sec = mktime(&tm); //<-convert tm to time_t
start.tv_usec = stoi(line); // <- set the usec from the stirng
//IF you want the other why around
strftime(tmbuf, sizeof tmbuf, " %F %H:%M:%S", localtime(&start.tv_sec));
snprintf(buf, sizeof buf, "%s.%06ld", tmbuf, start.tv_usec);
std::cout << tmbuf;
return 0;
}
output:
2020-07-06 09:30:00.646533

How to change the format of date and time with time_t?

time_t now = time(0);
std::string h = std::string (ctime (&now));
std::cout << "\nh: " << h;
Current output that I am receiving is: Thu Sep 14 10:58:26 2017
I want the output as 2017-08-26-16-10-56
What can I do to that output?
Use strftime, like this:
strftime (buffer, 80,"%Y-%m-%d-%H-%M-%S",timeinfo);
Full code:
#include <cstdio>
#include <ctime>
int main ()
{
time_t rawtime;
struct tm * timeinfo;
char buffer [80];
time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer, 80,"%Y-%m-%d-%H-%M-%S",timeinfo);
puts (buffer);
return 0;
}
Output:
2017-09-14-14-41-19
Use std::put_time
#include <iomanip>
time_t now = time(0);
std::string h = std::put_time(localtime(&now), "%F-%H-%M-%S");
std::cout << "\nh: " << h;
Output
h: 2017-09-14-05-54-02
Even better, use std::chrono
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std;
int main() {
auto now = chrono::system_clock::to_time_t(chrono::system_clock::now());
cout << put_time(localtime(&now), "%F-%H-%M-%S") << endl;
return 0;
}

How to convert time into an integer

I have the following code:
#include <ctime>
#include <stdio.h>
#include <iostream>
#include <chrono>
using namespace std;
const std::string currentDateTime() {
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%X", &tstruct);
return buf;
}
int main() {
std::cout << "Current Time is: " << currentDateTime() << std::endl;
return 0;
}
I compile this and i get: Current Time is: 18:30:11
I want to know how to convert that into an integer so it appears as just 18.5 or something along those lines. I want to do it because I want to create a timetable.
Example: if its 10:30, I want the program to be able to tell me what subject i have (for school).
Something like this:
if(time == 10.5)
std::cout<<(subject);
Any advice on how to do this? I'm fairly new to c++ and I'm not sure if I'm going about this the completely wrong way. Is there another way to do this?
Thanks in advance.
I suppose you mean converting the time to a floating point number. In your currentDateTime function you already use struct tm. Based on that you could get a float hour value by:
time_t now = time(0);
struct tm tstruct = *localtime(&now);
float f = tstruct.tm_hour + tstruct.tm_min / 60.0 + tstruct.tm_sec / 3600.0;
cout << f << endl; // prints 10.1025 at 10:06:09

Outputting Date and Time in C++ using std::chrono

I have been upgrading some old code and have been trying to update to c++11 where possible. The following code is how I used to display the time and date in my program
#include <iostream>
#include <string>
#include <stdio.h>
#include <time.h>
const std::string return_current_time_and_date() const
{
time_t now = time(0);
struct tm tstruct;
char buf[80];
tstruct = *localtime(&now);
strftime(buf, sizeof(buf), "%Y-%m-%d %X", &tstruct);
return buf;
}
I would like to output the current time and date in a similar format using std::chrono(or similar) but am unsure how to go about doing so. Any help would be greatly appreciated. Thanks
The <chrono> library only deals with time and not dates, except for the system_clock which has the ability to convert its timepoints to time_t. So using <chrono> for dates will not improve things much. Hopefully we get something like chrono::date in the not too distant future.
That said, you can use <chrono> in the following way:
#include <chrono> // chrono::system_clock
#include <ctime> // localtime
#include <sstream> // stringstream
#include <iomanip> // put_time
#include <string> // string
std::string return_current_time_and_date()
{
auto now = std::chrono::system_clock::now();
auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
return ss.str();
}
Note that std::localtime may cause data races. localtime_r or similar functions may be available on your platforms.
Update:
Using a new version of Howard Hinnant's date library you can write:
#include "date.h"
#include <chrono>
#include <string>
#include <sstream>
std::string return_current_time_and_date() {
auto now = std::chrono::system_clock::now();
auto today = date::floor<days>(now);
std::stringstream ss;
ss << today << ' ' << date::make_time(now - today) << " UTC";
return ss.str();
}
This will print out something like "2015-07-24 05:15:34.043473124 UTC".
On an unrelated note, returning const objects has become undesirable with C++11; const return values cannot be moved from. I also removed the trailing const because trailing const is only valid for member functions and this function has no need to be a member.
Here's a C++20 solution:
#include <chrono>
#include <format>
std::string get_current_time_and_date()
{
auto const time = std::chrono::current_zone()
->to_local(std::chrono::system_clock::now());
return std::format("{:%Y-%m-%d %X}", time);
}
std::chrono::time_zone::to_local converts a system clock time point (std::chrono::time_point<std::chrono::system_clock, TDuration>) to a local time point (std::chrono::local_time<TDuration>). This local time point can then be formatted using std::format with formatting options similar to strftime.
Currently, only MSVC has implemented std::format. The calendar and timezone additions to chrono
are currently "partially" implemented by Clang and GCC, but check here for the updated status: https://en.cppreference.com/w/cpp/compiler_support. For more information about the chrono library, read here: https://en.cppreference.com/w/cpp/chrono.
An example:
#include <iostream>
#include <chrono>
#include <ctime>
std::string getTimeStr(){
std::time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::string s(30, '\0');
std::strftime(&s[0], s.size(), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
return s;
}
int main(){
std::cout<<getTimeStr()<<std::endl;
return 0;
}
Output as below:
For getting also milliseconds, I use chrono and C function localtime_r which is thread-safe (in opposition to std::localtime).
#include <iostream>
#include <chrono>
#include <ctime>
#include <time.h>
#include <iomanip>
int main() {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::time_t currentTime = std::chrono::system_clock::to_time_t(now);
std::chrono::milliseconds now2 = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
struct tm currentLocalTime;
localtime_r(&currentTime, &currentLocalTime);
char timeBuffer[80];
std::size_t charCount { std::strftime( timeBuffer, 80,
"%D %T",
&currentLocalTime)
};
if (charCount == 0) return -1;
std::cout << timeBuffer << "." << std::setfill('0') << std::setw(3) << now2.count() % 1000 << std::endl;
return 0;
}
For format: http://www.cplusplus.com/reference/ctime/strftime/
bames53 solutions are good, but do not compile on my VS2017. The solution with ctime does not compile because localtime is very deprecated. The one with date.h does not compile with the current date.h I just took off github even though the documentation says they should, because today cannot be streamed as is. I omitted the includes but here is code that works:
void TimeTest()
{
auto n = std::chrono::system_clock::now();
auto in_time_t = std::chrono::system_clock::to_time_t(n);
std::tm buf;
localtime_s(&buf, &in_time_t);
std::cout << std::put_time(&buf, "%Y-%m-%d %X") << std::endl;
}
// I just added date.h from this link's guthub to the project.
// https://howardhinnant.github.io/date/date.html
void TimeTest1() {
auto now = std::chrono::system_clock::now();
auto today = floor<date::days>(std::chrono::system_clock::now());
std::cout << date::year_month_day{ today } << ' ' << date::make_time(now - today) << std::endl;
}
// output is
// 2018-04-08 21:19:49
// 2018-04-08 18:19:49.8408289
Feel free to fix bames53 solution and delete mine. My text just won't fit in a comment. I'm sure it can save many people from grief.
The fmt library has the ability to format tm structures: it has the same spec as strftime.
#include <ctime>
#include <fmt/chrono.h>
std::string current_datetime(void)
{
std::time_t tt = std::time(nullptr);
std::tm *tm = std::localtime(&tt);
return fmt::format("{:%Y%m%d}", *tm);
}
Although correct answers were already given, I decided to implement one more solution that outputs also fractional part of second.
You may notice in my code that sometimes I subtract one second from time_t value, - std::chrono::seconds(1), it is because according to documentation to_time_t() may round value instead of truncating (according to doc "If std::time_t has lower precision, it is implementation-defined whether the value is rounded or truncated"), hence I have to subtract 1 second to make it truncated time.
Try it online!
#include <chrono>
#include <string>
#include <sstream>
#include <iomanip>
std::string FormatTime(std::chrono::system_clock::time_point tp) {
std::stringstream ss;
auto t = std::chrono::system_clock::to_time_t(tp);
auto tp2 = std::chrono::system_clock::from_time_t(t);
if (tp2 > tp)
t = std::chrono::system_clock::to_time_t(tp - std::chrono::seconds(1));
ss << std::put_time(std::localtime(&t), "%Y-%m-%d %T")
<< "." << std::setfill('0') << std::setw(3)
<< (std::chrono::duration_cast<std::chrono::milliseconds>(
tp.time_since_epoch()).count() % 1000);
return ss.str();
}
std::string CurrentTimeStr() {
return FormatTime(std::chrono::system_clock::now());
}
#include <iostream>
int main() {
std::cout << CurrentTimeStr() << std::endl;
}
Example Output:
2021-12-02 04:10:51.876
As suggested by #AndyK, starting from C++20 you can use std::chrono::current_zone() and its method to_local(), they return std::chrono::local_time which is directly convertible to your desired string format by outputting to std::ostringstream or through std::format(). Whole function becomes very short:
#include <chrono>
#include <string>
#include <sstream>
#include <iostream>
std::string CurrentTimeStr() {
return (std::ostringstream{} << std::chrono::current_zone()->to_local(
std::chrono::system_clock::now())).str().substr(0, 23);
}
int main() {
std::cout << CurrentTimeStr() << std::endl;
}
But right now not all compilers support this current_zone() function, online GodBolt servers failed to compile it on trunk CLang and GCC, but MSVC compiles it well. Although my local laptop installation of CLang compiled it too.
You can improve the answer from #bames53 by using Boost lexical_cast instead of string stream manipulations.
Here is what I do:
#include <boost/lexical_cast.hpp>
#include <ctime>
std::string return_current_time_and_date() {
auto current_time = std::time(0);
return boost::lexical_cast<std::string>(std::put_time(std::gmtime(& current_time), "%Y-%m-%d %X"));
}

String representation of time_t?

time_t seconds;
time(&seconds);
cout << seconds << endl;
This gives me a timestamp. How can I get that epoch date into a string?
std::string s = seconds;
does not work
Try std::stringstream.
#include <string>
#include <sstream>
std::stringstream ss;
ss << seconds;
std::string ts = ss.str();
A nice wrapper around the above technique is Boost's lexical_cast:
#include <boost/lexical_cast.hpp>
#include <string>
std::string ts = boost::lexical_cast<std::string>(seconds);
And for questions like this, I'm fond of linking The String Formatters of Manor Farm by Herb Sutter.
UPDATE:
With C++11, use to_string().
Try this if you want to have the time in a readable string:
#include <ctime>
std::time_t now = std::time(NULL);
std::tm * ptm = std::localtime(&now);
char buffer[32];
// Format: Mo, 15.06.2009 20:20:00
std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", ptm);
For further reference of strftime() check out cppreference.com
The top answer here does not work for me.
See the following examples demonstrating both the stringstream and lexical_cast answers as suggested:
#include <iostream>
#include <sstream>
int main(int argc, char** argv){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::stringstream stream;
stream << t;
std::cout << t << "/" << stream.str() << std::endl;
}
Output: 1485498912/1485498912
Found here
#include <boost/lexical_cast.hpp>
#include <string>
int main(){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::string ts = boost::lexical_cast<std::string>(t);
std::cout << t << "/" << ts << std::endl;
return 0;
}
Output: 1485498912/1485498912
Found: here
The 2nd highest rated solution works locally:
#include <iostream>
#include <string>
#include <ctime>
int main(){
const char *time_details = "2017-01-27 06:35:12";
struct tm tm;
strptime(time_details, "%Y-%m-%d %H:%M:%S", &tm);
time_t t = mktime(&tm);
std::tm * ptm = std::localtime(&t);
char buffer[32];
std::strftime(buffer, 32, "%Y-%m-%d %H:%M:%S", ptm);
std::cout << t << "/" << buffer;
}
Output: 1485498912/2017-01-27 06:35:12
Found: here
Standard C++ does not have any time/date functions of its own - you need to use the C localtime and related functions.
the function "ctime()" will convert a time to a string.
If you want to control the way its printed, use "strftime". However, strftime() takes an argument of "struct tm". Use "localtime()" to convert the time_t 32 bit integer to a struct tm.
The C++ way is to use stringstream.
The C way is to use snprintf() to format the number:
char buf[16];
snprintf(buf, 16, "%lu", time(NULL));
Here's my formatter -- comments welcome. This q seemed like it had the most help getting me to my a so posting for anyone else who may be looking for the same.
#include <iostream>
#include "Parser.h"
#include <string>
#include <memory>
#include <ctime>
#include <chrono>
#include <iomanip>
#include <thread>
using namespace std;
string to_yyyyMMddHHmmssffffff();
string to_yyyyMMddHHmmssffffff() {
using namespace std::chrono;
high_resolution_clock::time_point pointInTime = high_resolution_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(pointInTime);
microseconds micros = duration_cast<microseconds>(pointInTime.time_since_epoch());
std::size_t fractional_microseconds = micros.count() % 1'000'000;
std:stringstream microstream;
microstream << "00000" << fractional_microseconds;
string formatted = microstream.str();
int index = formatted.length() - 6;
formatted = formatted.substr(index);
std::stringstream dateStream;
dateStream << std::put_time(std::localtime(&now_c), "%F %T") << "." << formatted;
formatted = dateStream.str();
return formatted;
}
There are a myriad of ways in which you might want to format time (depending on the time zone, how you want to display it, etc.), so you can't simply implicitly convert a time_t to a string.
The C way is to use ctime or to use strftime plus either localtime or gmtime.
If you want a more C++-like way of performing the conversion, you can investigate the Boost.DateTime library.
localtime did not work for me. I used localtime_s:
struct tm buf;
char dateString[26];
time_t time = time(nullptr);
localtime_s(&buf, &time);
asctime_s(dateString, 26, &buf);