COleDateTime: problem converting it to a DATE

G

Guest

We are experiencing a problem with COleDateTime while migrating our MFC&ATL project from VC++6.0 to VC++7.1 (Visual Studio .NET 2003).
COleDateTime has a DATE conversion operator that in 7.1 asserts when the date state is not valid. But we may need to pass NULL dates (read from a database) to our COM clients! - Yes, this problem doesn't occur in Release version, but we can't have a Debug version that asserts from time to time :)
A solution could be a small inline wrapper function that returns (DATE)0 when the state is null and else it calls the conversion operator, but it seems a bit "dirty".
Any suggestion?

Thank you very much
Paolo
 
D

David Lowndes

We are experiencing a problem with COleDateTime while migrating our MFC&ATL project from VC++6.0 to VC++7.1 (Visual Studio .NET 2003).
COleDateTime has a DATE conversion operator that in 7.1 asserts when the date state is not valid. But we may need to pass NULL dates (read from a database) to our COM clients!

Paolo,

Which function in the MFC/ATL COleDateTime sources has this ASSERT?

Can you give a minimal example of how to reproduce this behaviour in a
manner that reproduces your more complex situation with the database
(but without the database of course).

Dave
 
G

Guest

David Lowndes said:
Which function in the MFC/ATL COleDateTime sources has this ASSERT?
Can you give a minimal example of how to reproduce this behaviour in a
manner that reproduces your more complex situation with the database
(but without the database of course).


***Server side***
When I read a date from the database using ADO, and that date is NULL (very likely, e.g. no starting time has been defined) I get a VT_NULL variant.
So I use the following code (where lpFieldName is a LPCTSTR, and pRecordset is an ADO Recordset (ordinary ADO, not .NET)

_variant_t vtFld;
COleDateTime time;
vtFld = pRecordset->Fields->GetItem(lpFieldName)->Value;
switch(vtFld.vt)
{
case VT_DATE:
{
COleDateTime dt(vtFld);
time = dt;
}
break;
case VT_EMPTY:
case VT_NULL:
time.SetStatus(COleDateTime::null);
}

***Client side***
When I want to convert the COleDateTime to a DATE for a COM client, I write (of course, m_dtEstmStrtTm is a COleDateTime and dOutEstmStartTm is a DATE) :

dOutEstmStartTm = DATE(m_dtEstmStrtTm);

or simply:

dOutEstmStartTm = m_dtEstmStrtTm; // the same!

The source code for COleDateTime in 6.0 reads:

_AFXDISP_INLINE COleDateTime::blush:perator DATE() const
{ return m_dt; }

But in 7.1 it reads:

ATLCOMTIME_INLINE COleDateTime::blush:perator DATE() const throw()
{
ATLASSERT(GetStatus() == valid);
return( m_dt );
}

that's not documented in MSDN 2003 (at least, I didn't find anything...) !

Shall I change the server side (i.e. avoid setting the status of COleDateTime to COleDateTime::null) or the client side (i.e. return zero when the status is COleDateTime::null) ?
Is zero the same as a "null" datetime? How can my clients tell a missing date from a "zero" date? I don't want them to display "midnight, 30 December 1899"!

Thank you very much
Paolo
 
D

David Lowndes

The source code for COleDateTime in 6.0 reads:
_AFXDISP_INLINE COleDateTime::blush:perator DATE() const
{ return m_dt; }

But in 7.1 it reads:

ATLCOMTIME_INLINE COleDateTime::blush:perator DATE() const throw()
{
ATLASSERT(GetStatus() == valid);
return( m_dt );
}

Paolo,

FWIW, it's currently the same in the VS2005 pre-release version.
Shall I change the server side (i.e. avoid setting the status of COleDateTime to COleDateTime::null) or the client side (i.e. return zero when the status is COleDateTime::null) ?
Is zero the same as a "null" datetime? How can my clients tell a missing date from a "zero" date? I don't want them to display "midnight, 30 December 1899"!

I'm really not sure what to recommend as your best course of action.
Zero isn't the same as a null datetime.

This isn't something I've come across (never doing anything with
databases). The best I can recommend is to check the status yourself
and code around the difference appropriately. If you feel that the
current behaviour is wrong by design, I suggest that you contact MS
product support (by telephone) and raise the issue with them. If you
make your case well enough, maybe it'll be changed for VS2005.

Dave
 
G

Guest

David Lowndes said:
FWIW, it's currently the same in the VS2005 pre-release version.
I'm really not sure what to recommend as your best course of action.
Zero isn't the same as a null datetime.

You're quite right. I did some digging, and discovered that with the previous version (compiled with VC++6.0), a "null" date was silently converted into a zero date. Clients (in our case, Visual Basic clients) can't tell zero from null, unless you use a VARIANT instead of a DATE. But I can't use a VARIANT, as a COM interface cannot be changed. I can see only one solution: explicitly use a zero date - and document that, in our application, a zero date means no date (Most of our clients assume that already). Can you figure a factory job that starts on January 1, 1900 ? :)
If you feel that the
current behaviour is wrong by design, I suggest that you contact MS
product support (by telephone) and raise the issue with them. If you
make your case well enough, maybe it'll be changed for VS2005.

No, that's OK, now I've got it: the assert is there to warn you: "hey, programmer, remember that DATE cannot represent null, unpredictable trouble may occur!!!".
But I think it should have been documented in MSDN -- It would have saved me from this headache!

Thank you very much for your reply
Paolo
 
R

Ronald Laeremans [MSFT]

I agree, I'll see what we can do for the 8.0 documentation to make this
clear.

Ronald Laeremans
Visual C++ team
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top