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