want to convert ColeDateTime to CTime - mfc

I am reading a datetime from database in a ColeDateTime format. I want to convert it to CTime to get the date month year and time.
CString repDt; //**this will hold the datetime which i read from Database**
COleDateTime dt;
//**my datetime format is mm/dd/yyyy.**
dt.ParseDateTime(repDt); **//this line of code gives exception**
CTime t(dt.GetYear(), dt.GetMonth(), dt.GetDay(), dt.GetHour(),
dt.GetMinute(), dt.GetSecond());
m_time=t.GetTime();
Please give me some solution how could I do this?
Thanks in advance.

The CTime constructor accepts both SYSTEMTIME and DBTIMESTAMP structures, so both these will work:
SYSTEMTIME st;
if (dt.GetAsSystemTime(st))
t = CTime(st);
,
DBTIMESTAMP dbts;
if (dt.GetAsDBTIMESTAMP(dbts))
t = CTime(dbts);

Please try this
COleDateTime dt=COleDateTime(2013, 12, 12,12,12,56);
CTime ctime;
SYSTEMTIME systime;
dt.GetAsSystemTime(systime);
ctime = CTime(systime);

Related

How can I parse a std::string (YYYY-MM-DD) into a COleDateTime object?

I have a COleDateTime object and I want to parse a date string in the format YYYY-MM-DD.
The string variable, for example, is:
std::string strDate = "2022-07-04";
COleDateTime allows me to use ParseDateTime to parse a string, but I see no way to tell it what format the components of the date string are. In C# I can do such with DateTime.Parse....
Why not just a simple formatted input.
std::stringstream ss(strDate);
int year, month, day;
char dash;
ss >> year >> dash >> month >> dash >> day;
COleDateTime(year, month, day, 0, 0, 0);
Based on the suggestion by #xMRi in the comments I have decided to use:
CString strDutyMeetingDate = CString(tinyxml2::attribute_value(pDutyWeek, "Date").c_str());
int iDay{}, iMonth{}, iYear{};
if(_stscanf_s(strDutyMeetingDate, L"%d-%d-%d", &iYear, &iMonth, &iDay) == 3)
{
const auto datDutyMeetingDate = COleDateTime(iYear, iMonth, iDay, 0, 0, 0);
}
COleDateTime::ParseDateTime uses default parameter LANG_USER_DEFAULT, it can be called as
COleDateTime dt;
dt.ParseDateTime("2022-07-04");
Or
dt.ParseDateTime("2022-07-04", VAR_DATEVALUEONLY, LANG_USER_DEFAULT);
"2022-07-04" uses long date format so it should be safe, because it is clear that the year is at the start, and month is expected to be in the middle. I believe any LCID should return 2022-July-4th (I am 60% sure!)
If the date string was short, it could get confused with MM/DD/YY format, but that's not a problem here.
To make the lcid manually, see the English-US example below, although it should not be necessary in this case.
LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);

Convert Long of Unix Epoch Timestamp to Real Date/Time

I have attempted to find an answer to this question but the sources I have found do not properly convert the time. Originally I have the timestamp in a string as I am getting the timestamp from a .json web scraping program but want to convert it to a readable date/time. My latest attempt to do the conversion was to convert the string into a long and the long to time_t and then use strftime() but that does not produce the correct answer.
Here is the code where I converted the string to a long and then to time_t and then used strftime()
std::string timeStampToRead(const time_t rawtime)
{
struct tm *dt;
char buffer [30];
dt = localtime(&rawtime);
strftime(buffer, sizeof(buffer), "%m%d %H%M", dt);
return std::string(buffer);
}
int main()
{
std::string epochT = "1604563859000";
long e = atol(epochT.c_str());
const time_t rawtime = (const time_t)e;
std::string time = timeStamptToRead(rawtime);
return 0;
}
The result of this code is 0808 1703
I also attempted to do something very similar to above but changed timeStampToRead to the following
std::string timeStampToRead(const time_t rawtime)
{
struct tm *dt;
char buffer [30];
dt = localtime(&rawtime);
return asctime(dt);
}
This returns Mon Aug 8 17:03:20 which is also incorrect
The correct answer should be Thursday, November 5, 2020 8:10:59 UTC or Thursday, November 5, 2020 1:10:59 locally (not necessarily in that exact format just the correct month, day, and time is important)
I have tested the outcome of converting the string to a long and that is working correctly so I am thinking the error is either in converting the long to time_t or the process of using the time_t to get a readable format of the time. Of the two options, I think it is more likely the conversion from long to time_t is the issue but can't find another way to do the conversion.
I was hoping there was an easy way to directly take the string and convert it but I cannot find any information on that anywhere so that is why I resulted to converting the string to long and then to time_t. Basically, I can't figure out how to convert a string or long unix epoch timestamp to time_t to convert it to a readable format, or at least that is where I am assuming the error is. If anyone could point me in the right direction to get this conversion code working I would greatly appreciate it.
After some further digging, I have found my error and determined the best route
std::string epochT = "1604563859000";
long e atol(epochT.c_str());
const time_t rawtime = e/1000;
struct tm * dt;
dt = localtime(&rawtime);
std::string readable = asctime(dt);
This code will be inside a for loop that iterates through vectors of strings so epochT will be dependent on the elements in the vector and the current element, but this works and outputs the correct answer of Thu Nov 5 01:10:59 2020 local time.

Converting string to TDateTime in C++Builder 2009

I try to convert strings in specific formats to TDateTime using C++Builder 2009:
TDateTime dt, dt2;
TFormatSettings FS, FS2;
UnicodeString datestring = "17/10/2017 13:24:33";
UnicodeString datestring2 = "2017.17.10 13:24:33";
FS.DateSeparator = '/';
FS.ShortDateFormat = "dd/mm/yyyy";
FS.LongTimeFormat = "hh:nn:ss";
FS.TimeSeparator = ':';
FS2.DateSeparator = '.';
FS2.ShortDateFormat = "yyyy.dd.mm";
FS2.LongTimeFormat = "hh:nn:ss";
FS2.TimeSeparator = ':';
try{
dt = StrToDateTime(datestring, FS);
dt2 = StrToDateTime(datestring2,FS2);
}catch(EConvertError& e)
{
int a = 2;
}
Conversion of dt is ok, but conversion of dt2 throws an exception :
''2017.17.10 13:24:33'' is not a valid date and time
Per the documentation of StrToDate() (which also applies to StrToDateTime()):
S must consist of two or three numbers, separated by the character defined by the DateSeparator global variable or its TFormatSettings equivalent. The order for month, day, and year is determined by the ShortDateFormat global variable or its TFormatSettings equivalent--possible combinations are m/d/y, d/m/y, and y/m/d.
The date that is failing is in y/d/m format, which these RTL functions do not support. The date that works is in d/m/y format, which is supported.
Thank you all!
Ok now I know that, this date formats are unsupported by StrToDateTime. Solution of this problem is, convert and merge Windows ShortDateFormat and LongTimeFormat to format string accepted by strptime() from time.h. Then I use strptime() and create TDateTime from tm struct from time.h. I try to link docs but, in docs isn't any strptime func. I find this func in time.h from CodeGear RTL ver 13. I think this is equivalent to strptime

C++ mktime returning random dates

I'm trying to convert a date string to a time_t, but mktime() is returning seemingly random dates:
string datetime = "2014-12-10 10:30";
struct tm tmInfo;
strptime(datetime.c_str(), "%Y-%m-%d %H:%M", &tmInfo);
tmInfo.tm_isdst = 0;
time_t eventTime = mktime(&tmInfo);
eventTime ranges wildly from the 1970s to the 2030s. The tmInfo struct holds the correct date, so the error must be happening in mktime(). Any ideas of what's going wrong?
You need to properly zero-initialize all of the other fields of the struct tm instance before calling strptime(), since it doesn't necessarily initialize every field. From the strptime() POSIX specification:
It is unspecified whether multiple calls to strptime() using the same tm structure will update the current contents of the structure or overwrite all contents of the structure. Conforming applications should make a single call to strptime() with a format and all data needed to completely specify the date and time being converted.
For example, this should suffice:
struct tm tmInfo = {0};
You have to initialize the struct to 0 beforehand or also input the seconds:
string datetime = "2014-12-10 10:30";
struct tm tmInfo = { 0 };
strptime(datetime.c_str(), "%Y-%m-%d %H:%M", &tmInfo);
or
string datetime = "2014-12-10 10:30:00";
struct tm tmInfo;
strptime(datetime.c_str(), "%Y-%m-%d %H:%M:%S", &tmInfo);
The below code would do the work, if you want current system time in an format
time_t current_time;
struct tm *loctime;
memset(buffer,0,strlen(buffer));
current_time = time(NULL);
loctime = localtime(&current_time);
strftime(buffer,250,"--> %d/%m/%y %H:%M:%S",loctime);

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