0

I try to convert strings in specific formats to TDateTime using C++Builder 2009:

TDateTime dt, dt2;
TFormatSettings FS, FS2;

UnicodeString datestring = "17/10/2017 13:24:33";
UnicodeString datestring2 = "2017.17.10 13:24:33";

FS.DateSeparator = '/';
FS.ShortDateFormat = "dd/mm/yyyy";
FS.LongTimeFormat = "hh:nn:ss";
FS.TimeSeparator = ':';

FS2.DateSeparator = '.';
FS2.ShortDateFormat = "yyyy.dd.mm";
FS2.LongTimeFormat = "hh:nn:ss";
FS2.TimeSeparator = ':';

try{
    dt = StrToDateTime(datestring, FS);
    dt2 = StrToDateTime(datestring2,FS2);
}catch(EConvertError& e)
{
    int a = 2;
}

Conversion of dt is ok, but conversion of dt2 throws an exception :

''2017.17.10 13:24:33'' is not a valid date and time

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
lgabryel
  • 109
  • 1
  • 9
  • Very strange date format, but the equivalent Delphi version of your test case works with FPC: https://www.ideone.com/Pr9ROO. Can't check what the real Delphi does right now. –  Oct 17 '17 at 12:36
  • Yes. On Lazarus 1.6.4 work fine, but on C++ Builder 2009 reise exception :( – lgabryel Oct 17 '17 at 13:03
  • 1
    You are declaring `TFormatSettings` variables, but you are not initializing them with defaults before then customizing their fields. You must initialize them using `TFormatSettings::Create()` or `GetLocaleFormatSettings()`. Also FYI, `StrToTime()` (and by extension, `StrToDateTime()` does not use `LongTimeFormat` – Remy Lebeau Oct 17 '17 at 15:45

2 Answers2

1

Per the documentation of StrToDate() (which also applies to StrToDateTime()):

S must consist of two or three numbers, separated by the character defined by the DateSeparator global variable or its TFormatSettings equivalent. The order for month, day, and year is determined by the ShortDateFormat global variable or its TFormatSettings equivalent--possible combinations are m/d/y, d/m/y, and y/m/d.

The date that is failing is in y/d/m format, which these RTL functions do not support. The date that works is in d/m/y format, which is supported.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Ok, but Windows support format yyyy.dd.mm - is some way to do this in Delphi/C++ without write my own implementation of parsing datetime string? Ofc I can write this function, but I want to use some existing lib ora api first. – lgabryel Oct 17 '17 at 16:04
  • @lukas.gab the RTL doesn't use OS APIs to parse the string, it is done manually. You will have to parse unsupported formats yourself – Remy Lebeau Oct 17 '17 at 16:05
  • Ok, thank you for your help. @hvd give us example in fpc, and this works. Doc of fpc specify only three formats too, like delphi doc. This mean, fpc, has bug or UB? This should be EConvertError exception in fpc ? – lgabryel Oct 17 '17 at 16:33
0

Thank you all!

Ok now I know that, this date formats are unsupported by StrToDateTime. Solution of this problem is, convert and merge Windows ShortDateFormat and LongTimeFormat to format string accepted by strptime() from time.h. Then I use strptime() and create TDateTime from tm struct from time.h. I try to link docs but, in docs isn't any strptime func. I find this func in time.h from CodeGear RTL ver 13. I think this is equivalent to strptime

lgabryel
  • 109
  • 1
  • 9