Search code examples
delphidelphi-10-seattle

Lose milliseconds on DateToISO8601


A lot of APIs want the ISO8601 without the milliseconds like this:

Get only orders which were placed after this timestamp. Should be in YYYY-MM-ddTHH:mm:ssZ format

I guess the main "issue" is the dot after the seconds (between seconds and milliseconds), one would have to url-encode the dot (http GET speaking), right?

SDateFormat: string = 'yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''.''zzz''Z'''; { Do not localize }

I am unable to lose the milliseconds.

DateToISO8601(TTimeZone.Local.ToUniversalTime(RecodeMilliSecond(now, 0), false), true)

This is my approach at the moment:

var
  utc: TDateTime;
...
  utc := TTimeZone.Local.ToUniversalTime(now);
  utc := RecodeMilliSecond(utc, 0);
  ... Format('/orders?storefront=de&ts_created_from_iso=%sT%sZ', [FormatDateTime('yyyy-mm-dd', utc), FormatDateTime('hh:nn:ss', utc)])

Any other ideas?


Solution

  • If I'm understanding your question correctly, you want to know how to make DateToISO8601() not output milliseconds, correct? The answer is, you can't. But, it would be very easy to strip off the milliseconds after the fact using System.Delete() or TStringHelper.Remove() since you know the exact offset and length of the milliseconds in the resulting string.

    var
      utc: TDateTime;
      iso: string;
    ... 
      utc := TTimeZone.Local.ToUniversalTime(Now);
      iso := DateToISO8601(utc, true);
      Delete(iso, 20, 4);
      ... '/orders?storefront=de&ts_created_from_iso=' + iso;
    

    Otherwise, just stick with your manually approach. However, you don't need RecodeMilliseconds(), and only 1 call to FormatDateTime() will suffice:

    const
      cISOFormat: string = 'yyyy''-''mm''-''dd''T''hh'':''nn'':''ss''Z''';
    var
      utc: TDateTime;
    ...
      utc := TTimeZone.Local.ToUniversalTime(Now);
      ... '/orders?storefront=de&ts_created_from_iso=' + FormatDateTime(cISOFormat, utc);