Search code examples
c++buildervcl

Not able to convert date/time to current locale


I am stuck trying to convert a date/time, which is read from a CSV file, into a format that is compatible with the current locale. The code has to run across different locales (for testing I have set the locale as Frisian (Netherlands)).

The date/time from the CSV is either 8/4/2022 10:13 or 05/16/2020 02:39:58.

I tried using the date (from the CSV) to set strStartDate as 8/4/2022 10:13, but the below code throws an EConvertError exception on the StrToDateTime() call:

TFormatSettings formatSettings;

formatSettings.ShortDateFormat = "mm/dd/yyyy";
formatSettings.LongTimeFormat = "hh:mm:ss";
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, formatSettings);

TDateTime outdateBegin = StrToDateTime(strStartDate, formatSettings);

The exception I get has the message:

'8/4/2022 10:13' is not a valid date and time

Any pointers on how to make the CSV date convert to a correct TDateTime format across different locales?


Solution

  • You should be populating the TFormatSettings with system defaults before you then customize its fields as needed. In the code you have shown, you are filling it with defaults after you customize it, so you are losing your customizations.

    Also, just an FYI, StrToDateTime() does not use the TFormatSettings::LongTimeFormat field at all. That field is used when converting a TDateTime into a String, not the other way around. StrToDateTime() uses TFormatSettings::ShortTimeFormat instead (but only when SysLocale::FarEast is true and TFormatSettings::ShortDateFormat contains dddd).

    Try this instead:

    // INITIALIZE THE FORMAT FIRST...
    TFormatSettings formatSettings;
    GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, formatSettings); // <-- moved here!
    // alternatively:
    // TFormatSettings formatSettings(LOCALE_SYSTEM_DEFAULT);
    
    // THEN CUSTOMIZE THE FORMAT AS NEEDED...
    formatSettings.ShortDateFormat = _D("mm/dd/yyyy");
    formatSettings.DateSeparator = _D('/');
    formatSettings.TimeSeparator = _D(':');
    
    // THEN USE THE FORMAT...
    TDateTime outdateBegin = StrToDateTime(strStartDate, formatSettings);