4

ISO 8601 describes a so called basic date format that does not use the dashes:

20140507 is a valid representation of the more readable 2014-05-07.

Is there a Delphi RTL function that can interpret that basic format and convert it to a TDateTime value?

I tried

function TryIso2Date(const _s: string; out _Date: TDateTime): Boolean;
var
  Settings: TFormatSettings;
begin
  Settings := GetUserDefaultLocaleSettings;
  Settings.DateSeparator := #0;
  Settings.ShortDateFormat := 'yyyymmdd';
  Result := TryStrToDate(_s, Date, Settings);
end;

TryIso2Date('20140507', dt);

but it did not work because the DateSeparator could not be found in the string.

The only solution I so far came up with (other than writing the parsing code myself) is adding the missing dashes before calling TryStrToDate:

function TryIso2Date(const _s: string; out _Date: TDateTime): Boolean;
var
  Settings: TFormatSettings;
  s: string;
begin
  Settings := GetUserDefaultLocaleSettings;
  Settings.DateSeparator := #0;
  Settings.ShortDateFormat := 'yyyy-mm-dd';
  s := Copy(_s,1,4) + '-' + Copy(_s, 5,2) + '-' + Copy(_s, 7);
  Result := TryStrToDate(_s, Date, Settings);
end;

TryIso2Date('20140507', dt);

This works, but it feels rather clumsy.

This is Delphi XE6, so it should have the most recent RTL possible.

dummzeuch
  • 10,975
  • 4
  • 51
  • 158
  • Not sure if the `RTL` has something that can help you, but `XSBuiltIn` does. It can be converted easily using `TXSDatetime`. Check @JeroenWiertPluimers conversion unit on his [blog](http://wiert.me/2011/08/18/iso-8601-date-time-and-datetime-in-delphi-was-simple-example-to-show-datetime-now-in-iso-8601-format-on-ideone-com-online-c-compiler-debugging-tool/). – Guillem Vicens Jun 08 '14 at 17:28
  • TXSDate.XSToNative throws EConvertError 'Invalid argument to date encode' for this format. – dummzeuch Jun 08 '14 at 17:40
  • The basic date format seems not supported by Indy's `IdDateTimeStamp.pas` either. But @RemyLebeau perhaps can verify that. – LU RD Jun 08 '14 at 21:35
  • You should also look at [link](http://stackoverflow.com/questions/6651829/how-do-i-convert-an-iso-8601-string-to-a-delphi-tdate/6653259#6653259) – crefird Jun 08 '14 at 22:47
  • @dummzeuch, just tested it and you are right. The problem lies when it tries to extract year, month and day. As it seems `TXSDate` is unable to do so without some kind of separator. – Guillem Vicens Jun 09 '14 at 06:32

1 Answers1

2

You can use Copy to pull out the values as you already do. And then you just need to encode the date:

function TryIso8601BasicToDate(const Str: string; out Date: TDateTime): Boolean;
var
  Year, Month, Day: Integer;
begin
  Assert(Length(Str)=8);
  Result := TryStrToInt(Copy(Str, 1, 4), Year);
  if not Result then
    exit;
  Result := TryStrToInt(Copy(Str, 5, 2), Month);
  if not Result then
    exit;
  Result := TryStrToInt(Copy(Str, 7, 2), Day);
  if not Result then
    exit;
  Result := TryEncodeDate(Year, Month, Day, Date);
end;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 2
    In a similar vein, you can convert the entire string to int first, then use div and mod to pull out the year, month and day. – W.Prins Jun 08 '14 at 17:47
  • 2
    Yes, I could. Since I already know that it is the described format. Too simple, I guess. Still, I wonder why apparently Delphi cannot handle it. – dummzeuch Jun 08 '14 at 17:54
  • @dummzeuch IMHO Delphi's dateutils unit is the worst unit in the entire Delphi standard library. It appears to even pre-date object orientation. Actually, Turbo Pascal had a function to convert a date into a record, which sadly means TP gave you a more structured way to work with dates than Delphi. :-( The answer to why Delphi cannot handle it is just that no one's revisited dateutils since around Delphi 1 and updated its minimal capabilities. Heck, our datetimes aren't even inherently timezone aware. :-( There's no problem parsing ISO 8601 in other languages. – alcalde Jun 09 '14 at 21:22
  • @alcalde That's unfair. There have been quite a few improvements in dateutils over the years. But it's far from perfect, that's true. – dummzeuch Jun 10 '14 at 08:31