C++ What is the correct use of LCID in COleDateTime for American Date

2.3k views Asked by At

I need to parse an american date string to extract the date.

  COleDateTime dData;
  LCID lcid = 0x409; // 0x409 is the locale ID for English US
  CString strDate;

  dData.ParseDateTime("10/1/2014 9:43:00 AM", VAR_DATEVALUEONLY);
  strDate = dData.Format(0, lcid);

I expect this to return 1-Oct-2014 but instead it return 10-Oct-2014

Can someone please tell me what I am doing wrong here?

2

There are 2 answers

0
wilx On

I think you want to pass the lcid to the ParseDateTime() too:

dData.ParseDateTime(L"10/1/2014 9:43:00 AM", VAR_DATEVALUEONLY, lcid);
0
Roman Ryltsov On

I suppose you are getting 10-Jan-2014, not 10-Oct-2014. Apart from your parsing without providing lcid argument (and using LANG_USER_DEFAULT instead - see another answer), the parsing code uses VarDateFromStr, which in turn - presumably - does not do complicated pattern matching and instead simply requests LOCALE_IDATE value for the locale.

The value of 1 (Day-Month-Year) you have is causing this order of values.

LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); // 0x409 is the locale ID for English US
TCHAR pszIDate[32] = { 0 };
ATLVERIFY(GetLocaleInfo(lcid, LOCALE_IDATE, pszIDate, _countof(pszIDate)) > 0);
_tprintf(_T("LOCALE_IDATE: %s\n"), pszIDate);
COleDateTime dData;
dData.ParseDateTime(_T("10/1/2014 9:43:00 AM"), VAR_DATEVALUEONLY, lcid); // LANG_USER_DEFAULT
_tprintf(_T("%s\n"), dData.Format(0, lcid));
dData.m_dt -= 1.0;
_tprintf(_T("%s\n"), dData.Format(0, lcid));

With (see "Short date" setting):

enter image description here

you get:

LOCALE_IDATE: 1
10-Jan-14
09-Jan-14

and with

enter image description here

you get:

LOCALE_IDATE: 0
10/1/2014
9/30/2014

I suppose you should rather avoid parsing date/time strings using this legacy API unless you just formatted the argument string back from value on the same system.