DATE to string

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I am writing a NON MFC C++ application (Plug-in for a 3rd party DB system).
The application is designed to synchronise data between MS Outlook and the DB
system. I am using smart pointers for the development which is fine and
sysnchronisation back and forth is working as expected. The problem I am
having is with the DATE type (implemented using an 8-byte floating-point
number. Days are represented by whole number increments starting with 30
December 1899, midnight as time zero. Hour values are expressed as the
absolute value of the fractional part of the number. ). MS Outlook uses the
DATE type for e-mail dates, appointment dates etc e.g
spMailItem->GetReceivedTime() which I need to convert to a string in a
readable format e.g "25/12/2006 10:29:00" I just cant seem to get this to
work. I also need to go the other way (string to DATE). Can anyone provide a
simple code example to do this for me as I have looked everywhere and cannot
find a NON MFC example that works.

Thanks.
 
Hi jwf!
The problem I am
having is with the DATE type (implemented using an 8-byte floating-point
number. Days are represented by whole number increments starting with 30
December 1899, midnight as time zero. Hour values are expressed as the
absolute value of the fractional part of the number. ).

First convert DATE to SYSTEMTIME:
- VariantTimeToSystemTime
then you can convert it to any string you want.

The other way:
SystemTimeToVariantTime

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
jwf said:
I am writing a NON MFC C++ application (Plug-in for a 3rd party DB system).
The application is designed to synchronise data between MS Outlook and the
DB
system. I am using smart pointers for the development which is fine and
sysnchronisation back and forth is working as expected. The problem I am
having is with the DATE type (implemented using an 8-byte floating-point
number. Days are represented by whole number increments starting with 30
December 1899, midnight as time zero. Hour values are expressed as the
absolute value of the fractional part of the number. ). MS Outlook uses
the
DATE type for e-mail dates, appointment dates etc e.g
spMailItem->GetReceivedTime() which I need to convert to a string in a
readable format e.g "25/12/2006 10:29:00" I just cant seem to get this to
work. I also need to go the other way (string to DATE). Can anyone
provide a
simple code example to do this for me as I have looked everywhere and
cannot
find a NON MFC example that works.

This is a simple one :)

VarFormatDateTime() from Oleaut32.dll
It takes a VARIANT* but the variant is vt = VT_DATE; just copy your date
value to the date member.

Secondly, if you want to pass a mask, you'd take VarFormat()...


VARIANT v={0};
v.vt = VT_DATE;
v.date = yourDate;
CComBSTR thFmt;
HRESULT hr = VarFormatDateTime(&v, 0, 0, &thFmt);

But I never use this function, I use a combination of VarFormat() and use
GetLocaleInfoW to get the date / time mask. That mask is passed to VarFormat
and there you go!
 
message
Of course, you should convert this into a function.

FYI

LCID lcid = GetThreadLocale();
SYSTEMTIME st={0};
CComBSTR fmt;
int lenReq = GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, NULL, 0);
if (lenReq > 0)
{
fmt.SetLength(lenReq - 1);
GetLocaleInfoW(lcid, LOCALE_SSHORTDATE, fmt, lenReq);
}

lenReq = GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, NULL, 0);
if (lenReq > 0)
{
text.SetLength(lenReq - 1);
GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, text, lenReq);
fmt.Append(L' ');
fmt += text; //now fmt contains eg mm-dd-yyyy hh:mm
}

VARIANT v={0};
v.vt = VT_DATE;
v.date = [yourdatehere]
HRESULT hr = VarFormatDateTime(&v, 0, 0, &fmt);
 
Jochen Kalmbach said:
Hi jwf!

First convert DATE to SYSTEMTIME:
- VariantTimeToSystemTime
then you can convert it to any string you want.

The other way:
SystemTimeToVariantTime

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/

Thanks for this Jochen your post was very useful. The full method I used to
get from DATE to string is below (for anyone interested):

// Variables
DATE MailDateTime;

LPSYSTEMTIME SysTime;

string FormattedDateTime;

std::ostringstream oss_date;



//Get mail received time from outlook to DATE
MailDateTime = spMailItem->GetReceivedTime();

//Convert DATE to LPSYSTEMTIME
VariantTimeToSystemTime(MailDateTime, SysTime);

//Build string stream from date parts for readable format day/month/year
oss_date << SysTime->wDay << "/" << SysTime->wMonth << "/" << SysTime->wYear;

//assign string stream to string
FormattedDateTime.assign(oss_date.str());
 
jwf said:
Thanks for this Jochen your post was very useful. The full method I used to
get from DATE to string is below (for anyone interested):

// Variables
DATE MailDateTime;

LPSYSTEMTIME SysTime;

string FormattedDateTime;

std::ostringstream oss_date;



//Get mail received time from outlook to DATE
MailDateTime = spMailItem->GetReceivedTime();

//Convert DATE to LPSYSTEMTIME
VariantTimeToSystemTime(MailDateTime, SysTime);

//Build string stream from date parts for readable format day/month/year
oss_date << SysTime->wDay << "/" << SysTime->wMonth << "/" << SysTime->wYear;

//assign string stream to string
FormattedDateTime.assign(oss_date.str());

Hi jwf,

When did you allocate memory for LPSYSTEMTIME? As it is now I think your
code will crash when you call VariantTimeToSystemTime. LPSYSTEMTIME is a
pointer to SYSTEMTIME structure, so you need to have a SYSTEMTIME
allocated to receive the value when you call VariantTimeToSystemTime, e.g.:

SYSTEMTIME st;
LPSYSTEMTIME SysTime = &st;

Ray
 
Ray said:
Hi jwf,

When did you allocate memory for LPSYSTEMTIME? As it is now I think your
code will crash when you call VariantTimeToSystemTime. LPSYSTEMTIME is a
pointer to SYSTEMTIME structure, so you need to have a SYSTEMTIME
allocated to receive the value when you call VariantTimeToSystemTime, e.g.:

SYSTEMTIME st;
LPSYSTEMTIME SysTime = &st;

Ray
Hi Ray

Thanks for this but it doesn't seem necessary to do this.. The code in my
post seems to run without problems. You will have to excuse my C++ is very
rusty been mainly coding in VB.NET the last 4 years. Can you see any issue
with this?

Thanks
 
Hi jwf!
Hi Ray

Thanks for this but it doesn't seem necessary to do this..

Of yourse: This *IS* necessary!!!

You have just a pointer to nirvana...

You *must not* use LPSYSTEMTIME, instead use SYSTETIME and pass a
pointer to this struct:


SYSTEMTIME st;
VariantTimeToSystemTime(dbl, &st);

Greetings
Jochen
 
Jochen Kalmbach said:
Hi jwf!


Of yourse: This *IS* necessary!!!

You have just a pointer to nirvana...

You *must not* use LPSYSTEMTIME, instead use SYSTETIME and pass a
pointer to this struct:


SYSTEMTIME st;
VariantTimeToSystemTime(dbl, &st);

Greetings
Jochen

Understood. I have updated code sample appropriately (hopefully there are no
further issues):

// Variables
DATE MailDateTime;

SYSTEMTIME SysTime;

string FormattedDateTime;

std::ostringstream oss_date;


//Get mail received time from outlook to DATE
MailDateTime = spMailItem->GetReceivedTime();

//Convert DATE to LPSYSTEMTIME
VariantTimeToSystemTime(MailDateTime, &SysTime);

//Build string stream from date parts for readable format day/month/year
oss_date << SysTime.wDay << "/" << SysTime.wMonth << "/" << SysTime.wYear <<
" " << SysTime.wHour << ":" << SysTime.wMinute << ":" << SysTime.wSecond;

//assign string stream to string
FormattedDateTime.assign(oss_date.str());

Thanks again
 
Hi jwf,

The fastest way to catch this kind of error is by running a Debug build
(as opposed to Release). In debug configuration, uninitialized pointers
like LPSYSTEMTIME are initialized to a value that'll give you illegal
access exception or something along that line when you try to
dereference it.

Like Jochen mentioned, your pointer points to nirvana, that is, nobody
knows where it points to :) (that is, you were *lucky* that your snippet
ran without problems!)

As a rule, watch out for those pointers that are redefined in Windows
SDK not to look like pointers anymore, e.g.: LPSYSTEMTIME, LPRECT,
LPVARIANT...

(why would anybody bother to come up with LPSYSTEMTIME where SYSTEMTIME*
would have just done as well is beyond me. Don't they like asterisks or
something? Or they hate double asterisks so one could say LPRECT*
instead of RECT**? Perhaps Raymond Chen has a blog about this... hmmm...)
 
(why would anybody bother to come up with LPSYSTEMTIME where SYSTEMTIME*
would have just done as well is beyond me. Don't they like asterisks or

Long long ago, when we all used 16-bit compilers, SYSTEMTIME* wouldn't be
good enough (see the SS, BS, and DS CPU registers -- yuck!).
You'd have:

typedef SYSTEMTIME *PSYSTEMTIME; // not usable as argument to a DLL
typedef SYSTEMTIME __far *LPSYSTEMTIME;

I think I got the __far in the right place, it means the pointer can
reference memory in a different segment . But it's easy to get confused
between:
(a) __far SYSTEMTIME*
(b) SYSTEMTIME __far*
(c) SYSTEMTIME* __far

so the typedefs were a lifesaver.

Somehow the Windows API team never broke the habit, although when all
pointers became 32-bit in the flat memory model, the PXYZ (non-far)
datatypes jsut disappeared.
 
Ben said:
Long long ago, when we all used 16-bit compilers, SYSTEMTIME* wouldn't be
good enough (see the SS, BS, and DS CPU registers -- yuck!).

<snip>

Thanks Ben... yeah, I guess I was lucky to start with Visual C++... 4.0
if memory serves--so I never really programmed Win16 and started right
away with 32-bit platforms. Well, lucky, or spoiled :)
 
Back
Top