Convert Date string to unix time stamp - c++

I have a string in the form "20190930_141414" which is the date 2019 09 30 14:14:14. How can I convert this to the unix time stamp in utc?

You can use streams with get_time and mktime to convert it to a time_t object (time since the epoch).
struct std::tm lTM;
std::istringstream lTimestamp( "20190930_141414" );
lTimestamp >> std::get_time = ( &lTM, "%Y%m%d_%H%M%S" );
std::time_t lEpoch = mktime( &lTM );

Related

C++ - Convert Given UTC Time string to Local time zone

We have string format UTC Time and we need to convert to Your Current time zone and in string format.
string strUTCTime = "2017-03-17T10:00:00Z";
Need to Convert above value to Local time in same string format.
Like in IST it would be "2017-03-17T15:30:00Z"
Got Solution...
1) Convert String formatted time to time_t
2) use "localtime_s" to Convert utc to local time.
3) use "strftime" to convert local time (struct tm format) to string format.
int main()
{
std::string strUTCTime = "2017-03-17T13:20:00Z";
std::wstring wstrUTCTime = std::wstring(strUTCTime.begin(),strUTCTime.end());
time_t utctime = getEpochTime(wstrUTCTime.c_str());
struct tm tm;
/*Convert UTC TIME To Local TIme*/
localtime_s(&tm, &utctime);
char CharLocalTimeofUTCTime[30];
strftime(CharLocalTimeofUTCTime, 30, "%Y-%m-%dT%H:%M:%SZ", &tm);
string strLocalTimeofUTCTime(CharLocalTimeofUTCTime);
std::cout << "\n\nLocal To UTC Time Conversion:::" << strLocalTimeofUTCTime;
}
std::time_t getEpochTime(const std::wstring& dateTime)
{
/* Standard UTC Format*/
static const std::wstring dateTimeFormat{ L"%Y-%m-%dT%H:%M:%SZ" };
std::wistringstream ss{ dateTime };
std::tm dt;
ss >> std::get_time(&dt, dateTimeFormat.c_str());
/* Convert the tm structure to time_t value and return Epoch. */
return _mkgmtime(&dt);
}

UTC Timestamp comparison

I'm working on a client-server custom application (to be run on linux), and one of the frames I send include a timestamp (ie the time at which the frame is send).
In order to make my application reliable, I used gmtime to produce the time on the client. I'm in Belgium, so right now the hour of the client VM is 2 hours later than the UTC time (because of the summer hour).
In the server side, I first convert the recieved string to a time_t type. I do this to use the difftime function to see if the timestamp is not too old.
Then, I generate a timestamp (in UTC time) again with gmtime, and I convert it to a time_t.
I compare then the two time_t to see the time difference.
I have got a problem with the conversion of the time at the server side. I use the same code as in the client, but the outputted gmtime is different...
Client Side : function to generate the timestamp, and export it to a string (time_str):
std::string getTime()
{
time_t rawtime;
struct tm * timeinfo;
char buffer[80];
time (&rawtime); // Get time of the system
timeinfo = gmtime(&rawtime); // Convert it to UTC time
strftime(buffer,80,"%d-%m-%Y %H:%M:%S",timeinfo);
std::string time_str(buffer); // Cast it into a string
cout<<"Time Stamp now (client) : "<<time_str<<endl;
return time_str;
}
And it produices this (at 9h33 local time) :
Time Stamp now : 06-04-2016 07:33:30
Server Side : fucntion to retrieve the timestamp, generate the newx time stamp, and compare them :
bool checkTimeStamp(std::string TimsStamp_str, double delay)
{
cout<<"TimeStamp recieved: "<<TimsStamp_str<<endl;
/* Construct tm from string */
struct tm TimeStampRecu;
strptime(TimsStamp_str.c_str(), "%d-%m-%Y %I:%M:%S", &TimeStampRecu);
time_t t_old = mktime(&TimeStampRecu);
/* Generate New TimeStamp */
time_t rawtime;
struct tm * timeinfo;
time (&rawtime); // Get time of the system
timeinfo = gmtime(&rawtime); // convert it to UTC time_t
time_t t2 = mktime(timeinfo); // Re-Cast it to timt_t struct
/* Convert it into string (for output) */
char buffer[80];
strftime(buffer,80,"%d-%m-%Y %H:%M:%S",timeinfo);
std::string time_str(buffer); // Cast it into a string
cout<<"Time Stamp now (server) : "<<time_str<<endl;
/* Comparison */
double diffSecs = difftime(t2, t_old);
cout<<diffSecs<<endl;
bool isTimeStampOK;
if (diffSecs < delay)
isTimeStampOK = true;
else
isTimeStampOK = false;
return isTimeStampOK;
}
And it produces this (at 9h33 in Belgium) :
TimeStamp recieved : 06-04-2016 07:33:30
Time Stamp now (server) : 06-04-2016 08:33:31
Why is the Server Time (8h33) neither in localtime (9h33), neither in UTC time (7h33) ?
Have I made a mistake in its generation ? I don't understand where, because these are the exact same code as in the client side...
There's a couple of errors in your code, some your fault, some not. The biggest problem here is that the C <time.h> API is so poor, confusing, incomplete and error prone that errors like this are very nearly mandatory. More on that later.
The first problem is this line:
struct tm TimeStampRecu;
It creates an uninitialized tm and then passes that into strptime. strptime may not fill in all the fields of TimeStampRecu. You should zero-initialize TimeStampRecu like this:
struct tm TimeStampRecu{};
Next problem:
strptime(TimsStamp_str.c_str(), "%d-%m-%Y %I:%M:%S", &TimeStampRecu);
The 12-hour time denoted by %I is ambiguous without an AM/PM specifier. I suspect this is just a type-o as it is the only place you use it.
Next problem:
gmtime time_t -> tm UTC to UTC
mktime tm -> time_t local to UTC
That is, mtkime interprets the input tm according to the local time of the computer it is running on. What you need instead is:
timegm tm -> time_t UTC to UTC
Unfortunately timegm isn't standard C (or C++). Fortunately it probably exists anyway on your system.
With these changes, I think your code will run as expected.
If you are using C++11, there is a safer date/time library to do this here (free/open-source):
https://github.com/HowardHinnant/date
Here is your code translated to use this higher-level library:
std::string getTime()
{
using namespace std::chrono;
auto rawtime = time_point_cast<seconds>(system_clock::now());
auto time_str = date::format("%d-%m-%Y %H:%M:%S", rawTime);
std::cout<<"Time Stamp now (client) : "<<time_str<< '\n';
return time_str;
}
bool checkTimeStamp(std::string TimsStamp_str, std::chrono::seconds delay)
{
using namespace std::chrono;
std::cout<<"TimeStamp recieved: "<<TimsStamp_str<< '\n';
/* Construct tm from string */
std::istringstream in{TimsStamp_str};
time_point<system_clock, seconds> t_old;
date::parse(in, "%d-%m-%Y %H:%M:%S", t_old);
/* Generate New TimeStamp */
auto rawtime = time_point_cast<seconds>(system_clock::now());
auto time_str = date::format("%d-%m-%Y %H:%M:%S", rawTime);
in.str(time_str);
time_point<system_clock, seconds> t2;
date::parse(in, "%d-%m-%Y %H:%M:%S", t2);
cout<<"Time Stamp now (server) : "<<time_str<<endl;
/* Comparison */
auto diffSecs = t2 - t_old;
cout<<diffSecs.count()<<endl;
bool isTimeStampOK;
if (diffSecs < delay)
isTimeStampOK = true;
else
isTimeStampOK = false;
return isTimeStampOK;
}
A timestamp is an absolute value. It doesn't depend on timezones or DST. It represents the number of seconds since a fixed moment in the past. The value returned by time() is the same, no matter what the timezone of the server is.
Your code doesn't produce timestamps but dates formatted for human consumption.
I recommend you use timestamps internally and format them to dates readable by humans only in the UI. However, if you need to pass dates as strings between various components of your application, also put the timezone in them.
I would write your code like this (using only timestamps):
// The client side
time_t getTime()
{
return time(NULL);
}
// The server side
bool checkTimeStamp(time_t clientTime, double delay)
{
time_t now = time(NULL);
return difftime(now, clientTime) < delay;
}
Update
If you have to use strings to communicate between client and server then all you have to do is to update the format string used to format the timestamps as dates (on the client) and parse the dates back to timestamps (on the server), to include the timezone you used to format the date.
This means add %Z into the format everywhere in your code. Use "%d-%m-%Y %H:%M:%S %Z". Btw, the code you posted now reads "%d-%m-%Y %I:%M:%S" in the call to strptime() and that will bring you another problem in the afternoon.
Remark
I always use "%Y-%m-%d %H:%M:%S %Z" because it is unambiguous and locale-independent. 06-04-2016 can be interpreted as April 6 or June 4, depending of the native language of the reader.

MongoDB bson_date_t to local time

I appended date to the mongodb like this
bson_append_date(b,"uploadDate",(bson_date_t)1000*time(NULL));
Do remember that this will append "milliseconds since epoch UTC" and saved as 2014-06-27 06:11:56
Now i am reading it out and it is giving milliseconds (1403852029) which is exactly right. Now i want to convert it into local time. I tried to use the localtime function of C++ but did get success as the time returned by mongodb is in int64_t.
if(bson_iterator_type(&it)==BSON_DATE)
bson_date_t date_it = bson_iterator_date( &it );
where bson_date_t is typedef int64_t bson_date_t;. Can anyone tell me how i can get the local time from the milliseconds.
Getting a valid time_t that would work with localtime should be exactly the opposite of what you are doing in the forward conversion:
bson_append_date(b,"uploadDate",(bson_date_t)1000*time(NULL));
To have a workable time_t, you should do following:
time_t rawTime = (time_t)(bson_iterator_date( &it ) / 1000);
struct tm * timeinfo = localtime (&rawTime);
One more method.
bson_date_t date_it = bson_iterator_date( &it );
struct tm* ts;
time_t epoch_time_as_time_t= date_it/1000;
ts=localtime(&epoch_time_as_time_t);
strftime(upload_Date,sizeof(upload_date),"%a %Y-%m-%d %H:%M:%S %Z",ts);

Attempting to convert a time_t data type to have (dd/mm/yyyy) format C++

My question is pretty much in the title. I have a function call with a parameter of type time_t, and I need to initialize a variable to today's date, month, and year, and send it via the argument. For example,
void WebCall(time_t TodaysDate)
Where TodaysDate is the populated variable with the format DD/MM/YYYY with the slashes included. Is this possible? I can't change the data type from time_t to SYSTEMTIME or anything else. This is coded in C++. Any Ideas?
If you mean time_t, you can format it using gmtime and strftime:
time_t TodaysDate= ...;
struct tm * ptm= gmtime(&time);
char buffer[80];
strftime(buffer, 80, "%d/%m/%Y", ptm);
time_t is "unix time" and is the number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC. As MSN answered you can convert that to a date using gmtime, for most common purposes, UTC is synonymous with GMT. You didn't specify in the question but if you need the local date use localtime instead of gmtime. Here's a function that'll do that for you and return a std::string:
#include <time.h>
#include <string>
std::string time_to_local_date( time_t utc )
{
struct tm *now = localtime(&utc);
char buffer[80];
strftime(buffer, 80, "%d/%m/%Y", now);
return std::string(buffer);
}

How do I change the default local time format in C++?

I have a function:
string get_current_time()
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
return asctime (timeinfo);
}
which returns time in the following format:
Fri Mar 18 11:25:04 2011
How do I change it so that it is returned in the following format?
2011 03-18 11-25-04 Fri
I want to use this for log file names.
As #0A0D suggested, whilst you can't change asctime, you can use strftime to format the data contained in your time_t:
string get_current_time()
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
char output[30];
strftime(output, 30, "%Y %m-%d %H-%M-%S %a", timeinfo);
return string(output);
}
(I've also dropped a copy on to IdeOne here.)
asctime() always returns in the format Www Mmm dd hh:mm:ss yyyy . It cannot be changed.
If you want to use a different format, look at strftime().