c++builder

C++ Builder 12 StrToDateTime Exception but C++ Builder 11 no exception


I have a CSV file with dates in the format "2021/04/25 12:47:54 pm GMT+8" which are stored in a String. I currently convert the date field in C++ Builder 11 with the following code without any issues.

    TFormatSettings FSG;
    TDateTime CsvDate;
    FSG.DateSeparator = '/';
    FSG.ShortDateFormat = "yyyy/mm/dd";
    FSG.LongTimeFormat = "h:nn:ss";
    FSG.TimeSeparator = ':';
    CsvDate = StrToDateTime(GoogleValue, FSG);

However, c++ Builder 12 seems to have changed something and now the time doesn't convert, I get an exception when StrToDateTime is called. Can someone tell me what has changed so I can get this working again.

EXCEPTION is:

First chance exception at $766698B2. Exception class EConvertError with message
 ''2024/01/17 10:40:45 pm GMT+8' is not a valid date and time'.
Process MyApp.exe (26032)

I tried adding

TFormatSettings FSG = TFormatSettings::Create("en-AU");

and

TFormatSettings FSG = TFormatSettings::Create();

Neither of these helped to remove the exception.


Solution

  • v11 and earlier didn't care if a GMT offset is present in the input string, they would stop parsing when the trailing AM/PM substring is reached, regardless of anything that follows it.

    In v12, there is new logic implemented that if the time portion of the input string either 1) fails to parse under the old v11 logic, or 2) parses successfully but any non-whitespace character other then '-' or '+' follows the time, then the time portion will be parsed using FSG.ShortTimeFormat - which you are not providing, which is why the function is now failing.

    Even if you did provide a ShortTimeFormat, the new parsing logic can still fail because it simply does not support GMT offsets.

    That being said, if ALL of your inputs end with GMT+8 specifically, then you can specify that in the ShortTimeFormat, eg:

    FSG.ShortTimeFormat = "h:nn:ss am/pm 'GMT+8'";
    

    Otherwise, if you strip off just the GMT prefix from the offset, that will also work and just be ignored:

    GoogleValue = "2021/04/25 12:47:54 pm +8";
    

    Otherwise, you will have to manually strip off the entire GMT+... substring from the input string:

    GoogleValue = "2021/04/25 12:47:54 pm";
    

    If you need the resulting TDateTime to include the GMT offset then you will have to parse the offset yourself and adjust the TDateTime accordingly.

    I have filed a bug report with Embarcadero regarding this breaking logic change:

    RSS-1014: [Try]StrToDateTime() fails with string that worked fine in earlier versions