在 DateToISO8601 上丢失毫秒

Lose milliseconds on DateToISO8601

很多 API 都需要像这样没有毫秒的 ISO8601:

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

我想主要的“问题”是秒后的点(秒和毫秒之间),必须对点进行 url 编码(http GET 说话),对吗?

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

我不能失去毫秒。

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

这是我目前的做法:

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)])

还有其他想法吗?

如果我没有正确理解你的问题,你想知道如何使 DateToISO8601() 不输出毫秒,对吗?答案是,你不能。但是,使用 System.Delete()TStringHelper.Remove() 可以很容易地去除毫秒数,因为您知道结果字符串中毫秒的确切偏移量和长度。

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;

否则,请坚持使用您的手动方法。但是,您不需要 RecodeMilliseconds(),只需调用 1 次 FormatDateTime() 就足够了:

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);

这是我们使用的套路:

  function DateTimeToXML(dtInput: TDateTime): String;
  var
    fmt: TFormatSettings;
  begin
    // If this will be used in a multithreaded environment then
    // you should use your own TFormatSettings to be thread safe
    fmt:=TFormatSettings.Create();      // initialize, it's on the stack so MUST NOT be freed
    DateTimeToString(Result, 'yyyy-mm-dd''T''hh:nn:ss''Z''',
                     TTimeZone.Local.ToUniversalTime(dtInput), fmt);
  end;