Dave Novo 51 Posted September 3, 2021 Hello Everyone, I am just wondering if below is simply a bug, or there is some method to the madness. One of the valid windows short date formats is the following So, one would think that if you change windows to the short date format above, and wrote the Delphi code fs:=TFormatSettings.Create; newDate:=StrToDate('05-Apr-17',fs) then you would get a valid date. However, you do not. I checked this on Win7 and Win10, with Delphi Sydney and Seattle. It is hard to believe something this ancient does not work. The fs record has the correct shortMonthNames loaded. There are a few strange issues. 1. The TFormatSettings.ShortDateFormat ends up being dd/MMM/yy because FixDateSeparator replaces the '-' with a '/'. I am not sure this is relevant though, as the TFormatSettings.DateSeparator is still '-' 2. The key thing that fails is TryStrToDate calls ScanDate which exits out because of if not (ScanNumber(S, Pos, N1, L1) and ScanChar(S, Pos, AFormatSettings.DateSeparator) and ScanNumber(S, Pos, N2, L2)) then Exit; i.e. it is trying to find a number, followed by a separator, followed by a number. Even though the current date format specifies that the month portion should be the short name format. Is there another date method I should be using that works more reliably. Or am I doing something wrong? Share this post Link to post
Uwe Raabe 1979 Posted September 3, 2021 This is documented behavior: Quote S must consist of two or three numbers System.SysUtils.StrToDate Share this post Link to post
Dave Novo 51 Posted September 3, 2021 Is there another method of conversion that can handle the entirety of the set of formats that windows supports for the current date format? Share this post Link to post
Uwe Raabe 1979 Posted September 3, 2021 Nothing I am aware of, but it can be achieved easily with a wrapper like this: S := '05-Apr-17'; for I := 1 to 12 do S := S.Replace(fs.ShortMonthNames[I], I.ToString); newDate := StrToDate(S, fs); Of course there is some room for improvements, but you get the idea. Share this post Link to post
Dave Novo 51 Posted September 9, 2021 Sure, but then we have to either use a code hook or remember to never use StrToDate and use StrtoDateWrapper (or whatever we call it). It is surprising that these dates formats are not supported. They have been in windows for ages. 1 Share this post Link to post
Uwe Raabe 1979 Posted September 9, 2021 21 minutes ago, Dave Novo said: Sure, but then we have to either use a code hook or remember to never use StrToDate and use StrtoDateWrapper (or whatever we call it). Or you place a replacement for StrToDate in a separate unit MyDateUtils or so and use that all over the your projects. At least that is less tedious than replacing all StrToDate calls and having to remember a new function name. 24 minutes ago, Dave Novo said: It is surprising that these dates formats are not supported. They have been in windows for ages. I suggest filing a feature request in Quality Portal. (didn't check if some already exists) Share this post Link to post
Fr0sT.Brutal 898 Posted September 9, 2021 1 hour ago, Dave Novo said: It is surprising that these dates formats are not supported +1. I was expecting BtoA(AtoB(A)) == A for any A 1 Share this post Link to post
Uwe Raabe 1979 Posted September 9, 2021 StrToDate and StrToDateTime fail if ShortDateFormat is dd-MMM-yy StrToDateTime doesn't recognise mmm / mmmm formats - undocumented Share this post Link to post
Dave Novo 51 Posted September 9, 2021 Thanks for looking up the links. I guess if the bug report is >5 years old about this, I will not hold my breath. Share this post Link to post
Joseph MItzen 246 Posted September 10, 2021 On 9/3/2021 at 5:51 PM, Uwe Raabe said: Nothing I am aware of Nothing that allows specifying the format in a template? OK, just looked; dang, the Datetime utilities are even worse than I remembered, and IMHO they're worse than Turbo Pascal's - which could convert a datetime into a record of all of its elements. With Delphi, datetime completely omits any type of dot notation and your datetime code ends up looking rather like LISP with all the parentheses. Whoever designed Delphi's datetime unit must have never seen another language's datetime library and been mad besides. So... many... functions. Except useful ones. The day Delphi gets optional parameters I'm writing an open source datetime unit for it. Even FreePascal can parse an arbitrary datetime string.... https://www.freepascal.org/docs-html/rtl/sysutils/formatdatetime.html Share this post Link to post
Dmitry Arefiev 100 Posted September 10, 2021 StrToDate in v11 supports MMM in date formats. 2 1 Share this post Link to post
Uwe Raabe 1979 Posted September 10, 2021 41 minutes ago, Dmitry Arefiev said: StrToDate in v11 supports MMM in date formats. Confirmed! 👍 1 Share this post Link to post
Dave Novo 51 Posted September 10, 2021 Wow, I wish every time I complained about something then a resolution fell out of the sky in 3 days 😀 1 Share this post Link to post
Joseph MItzen 246 Posted September 10, 2021 3 hours ago, Uwe Raabe said: Confirmed! 👍 Woo-hoo! Now they just need support for arbitrary formats and timezeone-aware datetimes.... Share this post Link to post
Dmitry Arefiev 100 Posted September 10, 2021 Arbitrary formats - are also supported in v 11. Timezeone-aware datetimes - there is no such report in quality.embarcadero.com 3 1 Share this post Link to post
Dmitry Arefiev 100 Posted September 12, 2021 But this also leads to incompatibility[ies], eg: https://quality.embarcadero.com/browse/RSP-35349 Share this post Link to post
Uwe Raabe 1979 Posted September 12, 2021 I have to admit that I learned about hh:nn being the correct format quite late in my career. Nevertheless is it correct and logical. Using hh:mm just opens a can of ambiguity, makes the implementation more complex, error prone and slow. Unfortunately MS is not so consistent and also uses hh:mm. Note, that while TFormatSettings.Invariant uses the hh:nn format, TFormatSettings.Create(Locale:TLocalId) still falls back to hh:mm mimicking the MS style: if Result.ShortTimeFormat = '' then Result.ShortTimeFormat := TimePrefix + HourFormat + ':mm' + TimePostfix; if Result.LongTimeFormat = '' then Result.LongTimeFormat := TimePrefix + HourFormat + ':mm:ss' + TimePostfix; While we probably cannot drop hh:mm for staying compatible with Windows and older versions, using hh:nn where ever possible for unambiguousness is not that a bad idea. 1 Share this post Link to post
Dmitry Arefiev 100 Posted September 12, 2021 Exactly, at first taking into account the support for "Arbitrary formats". Share this post Link to post
Joseph MItzen 246 Posted September 12, 2021 (edited) 2 hours ago, Uwe Raabe said: ... it correct and logical. Unfortunately MS is not so consistent and also uses hh:mm. Most things seem to use hh:mm. I was just trolling through Google and it looks like Oracle, PostgreSQL, Java all do. Python and C use good old-fashioned case sensitivity, with M for months and m for minutes. This seems to eliminate any ambiguity while still preserving the use of "m" for both months and minutes. Looks like case sensitivity 1, Delphi 0 here. EDIT: Today I learned that if you want to set the time to 00:00:00.00 UTC in PostgreSQL you can use "allballs" as the input string. I may need to file a Delphi feature request immediately.... Edited September 12, 2021 by Joseph MItzen 1 Share this post Link to post
Richard Wilson 0 Posted May 28 On 9/10/2021 at 11:06 PM, Dmitry Arefiev said: StrToDate in v11 supports MMM in date formats. Apparently they changed the parser to require date separators in the ShortDateFormat, so now setting ShortDateFormat := 'ddmmyyyy' and DateSeparator := '/' causes StrToDate('01/01/1970') to throw an Exception Share this post Link to post
Lajos Juhász 270 Posted May 28 37 minutes ago, Richard Wilson said: ShortDateFormat := 'ddmmyyyy' and DateSeparator := '/' causes StrToDate('01/01/1970') to throw an Exception Nothing was changed 01/01/1970 required date format dd/mm/yyyy. Tested with Delphi XE5: var f: TFormatSettings; begin f:=TFormatSettings.Create; f.ShortDateFormat:='dd/mm/yyyy'; f.DateSeparator:='/'; StrToDate('01011970', f); end; The result is as expected --------------------------- Debugger Exception Notification --------------------------- Project Project1.exe raised exception class EConvertError with message ''01011970' is not a valid date'. --------------------------- Break Continue Help --------------------------- Share this post Link to post