How to concatenate strings in the function m_stream in C++? - c++

I'm writing a logger for my program in C++.
I have this piece of code:
void Log::Write(char* logline)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
m_stream << asctime (timeinfo) << logline << endl;
}
This is a log
Tue Oct 11 13:07:28 2011
I want a different output on a single line like this:
Tue Oct 11 13:07:28 2011 - This is a log
How can I do it?
Thank you!

As it said in docs:
The string result produced by asctime contains exactly 26 characters and has the form Wed Jan 02 02:03:55 1980\n\0
So if you don't want to write line ending symbol you could use use 'write' function specifying exact amount of characters to write like this
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
m_stream.write( asctime (timeinfo), 24 );
m_stream << " - " << logline << std::endl;
Of course in that case you should write comment explaining why '24' is used...

Your problem is asctime():
http://www.cplusplus.com/reference/clibrary/ctime/asctime/
The string is followed by a new-line character ('\n') and the terminating null-character.
As the returned string is a C string, you could replace the \n with a \0:
char * str = asctime(timeinfo);
str[strlen(str) - 1] = '\0';
AS long as you don't call ctime or asctime again, the content won't be overwritten.

Related

Convert Date string to unix time stamp

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 );

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);
}

simple c++ time program error

I am messing around with the time header and have encountered an error:
invalid conversion from 'tm*' to 'time_t'
You can see the where the error is in the code below all the way at the bottom when I try to use the difftime function. I know im just doing something stupid and illegal but I cant see how I can get around this. If anyone has a solution let me know. Thanks!
The program is supposed to get the current time, take time input from a user, and then find the time difference.
Code:
#include <stdio.h>
#include <time.h>
int main ()
{
time_t rawtime;
struct tm * timeinfo;
struct tm * cur_timeinfo_hold;
int year, month ,day,hour,minute,second;
double dif;
/* prompt user for time to be compared*/
printf ("Enter year: "); scanf ("%d",&year);
printf ("Enter month: "); scanf ("%d",&month);
printf ("Enter day: "); scanf ("%d",&day);
printf ("Enter hour: "); scanf ("%d",&hour);
printf ("Enter minute: "); scanf ("%d",&minute);
printf ("Enter second: "); scanf ("%d",&second);
/* get current timeinfo*/
time ( &rawtime );
timeinfo = localtime ( &rawtime );
/* print it */
printf("The present time is: "); printf(asctime (timeinfo));
/* set current time into a new variable to use for difftime, since timeinfo, will be changed */
cur_timeinfo_hold = timeinfo;
/* modify current timeinfo to the user's choice */
timeinfo->tm_year = year - 1900;
timeinfo->tm_mon = month - 1;
timeinfo->tm_mday = day;
timeinfo->tm_hour = hour;
timeinfo->tm_min = minute;
timeinfo->tm_sec = second;
mktime ( timeinfo );
/* and print it */
printf ("time to compare: "); printf(asctime (timeinfo));
/* find time difference */
//dif = difftime (cur_timeinfo_hold,timeinfo); //error: invalid conversion from 'tm*' to 'time_t'
return 0;
}
mktime is a function. It accepts one parameter, a tm pointer, and returns a value, a time_t. It does not transform its argument from one type into another. Therefore, after you call mktime(timeinfo), your timeinfo variable is still a tm pointer.
The difftime function expects to receive two time_t values, so it won't accept cur_timeinfo_hold or timeinfo; they're the wrong type. The first variable's value came from converting rawtime to a tm pointer with localtime, so use that for the first parameter. When you later called mktime(timeinfo), it returned a time_t value, but you ignored the return value. Assign the return value to a variable so you can use it for the second difftime parameter.
time_t info = mktime(timeinfo);
// ...
dif = difftime(rawtime, info);
It's because difftime requires the raw time_t values, not the struct tm structures.
The prototype is:
double difftime(time_t time1, time_t time0);
What you'll need to do is leave the system time as it is (no localtime performed on it) and then properly convert your user-entered information into the equivalent time_t with mktime (or timegm if working with UTC times).
Then you can use difftime to get the difference. Effectively, something like:
time_t base, other;
struct tm tms;
double delta;
time (&base); // basetime is now.
tms.blah = blah; // for all blahs.
other = mktime (&tms); // get time_t for other time.
delta = difftime (other, base); // get difference.

GetTimeZoneInformation equivalent in ubuntu?

i am using GetTimeZoneInformation in windows...but not able to find any equivalent in linux.
Any idea??
i figured it out after some more debugging time related structures.
Its better to use struct tm * gmtime ( const time_t * timer ) which wll give the UTC time.
And can use tzset() and tzname[0] to get the timezone info.
You can use the following on Unix:
std::string LocalTimeZone()
{
time_t now = time(NULL);
struct tm tnow = *localtime(&now);
std::string tz = tnow.tm_zone;
std::cout << "Local timezone: " << tz << std::endl;
char buff[100];
strftime( buff, sizeof buff, "%a %b %d %Y %T %Z%z", &tnow );
std::vector<std::string> vec;
const std::string s(buff);
boost::split(vec, s, boost::is_any_of(" "));
std::vector<std::string>::iterator i = vec.end();
return *--i;
}
Which will give the current time zone as per the host machine's system settings.
Boost has Boost.Date_Time, containing a time zone database. You can use the same.

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().