2012年9月27日木曜日

TryStrToDateTime を完璧にする

※追記:2012/09/28 こちらの記事で下記の記事を修正しています



android Log Viewer というアンドロイド端末のログを見るツールを公開しています。

このロガーは、他のロガーから出力されるログを読み込むこともできるので、エラー発生先でログを取っておいて貰って、そのログを読み込む、といった用途にも使えます。
ですが、たまに読めないログが出てきて、その度に、ちょこちょこ直しています。

で、最近読めなかったのが adb 形式のログなのに各要素のセパレータが #$1d  じゃないもの。
で、なんで読めないのかなーと思っていたら TryStrToDateTime でこけていました。

こけた原因は DateSeparator が "-" になっていなかったから。
adb のデフォルトのセパレータは "/" ではなく "-" です。
そのため、そのまま TryStrToDateTime に流すと False を返します。

でもー。"-" も一般的だしー、そんなケチケチしないで全部見て欲しいよねーってことで、全部見るようにしました。

できたのが↓こちらになります

function TryStrToDateTimeEx(
  const iStr: String;
  out oDateTime: TDateTime): Boolean;
const
  DateSeps: array [0.. 1] of Char = ('/', '-');
  TimeSeps: array [0.. 1] of Char = (':', '.');
var
  FS: TFormatSettings;
  i, j: Integer;
begin
  FS := TFormatSettings.Create;

  for i := Low(DateSeps) to High(DateSeps) do begin
    FS.DateSeparator := DateSeps[i];

    for j := Low(TimeSeps) to High(TimeSeps) do begin
      FS.TimeSeparator := TimeSeps[j];

      Result := TryStrToDateTime(iStr, oDateTime, FS);
      if (Result) then
        Break;
    end;
  end;
end;

ソースはこちらになります(GitHub)


コードを見ていただければ判りますが、まあ単に思いつく限りのセパレータで試してるだけ。
これで、めでたくログを読めるようになりました。

ちなみに、昔は、なんか読めたような気がするなあって思って調べてみたんですが、こんな普遍的に見えるルーチンでも、かなりコードが変更されていました。
特に Delphi 7 と XE2 では全然違いましたよ。ええ。
XE2 と XE3 でも、軽微な修正が入っていて、若干違うわけです!
こんなルーチンも、改良されて行っているわけですね。
ちなみに、昔は読めたような気がするのは気のせいでした。

1 件のコメント: