【问题标题】:How can I filter a dataset in Delphi on a TDateTime field如何在 TDateTime 字段上过滤 Delphi 中的数据集
【发布时间】:2011-03-02 18:23:53
【问题描述】:

我有一个需要按时间过滤的数据集。例如我想要 TDateTime 字段中包含的时间在上午 6:00 到下午 6:00 之间的记录。

我的数据集包含一个名为 time_of_day 的字段,类型为 TDateTime。分配给该字段的值是一个时间,没有日期。

我尝试使用时间的字符串表示 (time_of_day >= '6:00 AM' and time_of_day <= '6:00 PM') 和浮点表示 (time_of_day >= 0.25 and time_of_day < 0.75) 创建过滤器字符串,但都没有成功。

我需要知道如何构造过滤器字符串以分配给 TDataSet.Filter 属性。

【问题讨论】:

  • 不确定这是否与您的情况相关,但您也可以考虑更改生成数据集的 SQL(除非您希望将丢弃的记录用于其他目的)。

标签: delphi datetime filter


【解决方案1】:

我认为这可能取决于短时间格式,但这对我使用 TADODataSet 有效。

ADODataSet1.Filter := 'TimeField = 11:00:00';
ADODataSet1.Filtered := True;

更全面的证明解决方案是使用 OnFilterRecord 事件。

procedure TForm4.ADODataSet1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
    if DataSet.FieldByName('TimeField').AsDateTime = FilterValue then
        Accept := True
    else
        Accept := False
end;

如果你需要间隔,它看起来像这样。

ADODataSet1.Filter := 'TimeField >= 10:00:00 and TimeField < 11:00:00';
ADODataSet1.Filtered := True;

OnFilterRecord

procedure TForm4.ADODataSet1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
    if (DataSet.FieldByName('DateField').AsDateTime >= FromTime) and
         (DataSet.FieldByName('DateField').AsDateTime < ToTime) then
        Accept := True
    else
        Accept := False
end;

如果您使用 AMPM 表示法,则需要将时间括在 '

ADODataSet1.Filter := 'TimeField >= ''10:00 AM'' and TimeField < ''11:00 AM''';
ADODataSet1.Filtered := True;

但我真的会推荐 OnFilterRecord,这样您就不必担心时间格式。

【讨论】:

  • 对于 OnFilterRecord,我更喜欢 Accept := &lt;FilterTest&gt;; 而不是 if..else。不过,很好的答案。 :) 我会给你一个 +1 的彻底性(我也有这个问题的答案)。
  • 我的过滤器表达式是根据用户输入动态生成的,因此 OnFilterRecord 事件不实用。条件的数量和运算符的类型差异很大。收到您的回答后,我确实将过滤器更改为使用 ShortTime 格式,并且效果正确。
【解决方案2】:

TDateTime 在 Delphi 中是 double 类型,其中整数部分是自 1899 年 12 月 30 日以来的天数,小数部分(小数)是时间。

中午的时间(没有日期部分)将被指示为 0.5,这意味着上午 6:00 将是 0.25(确切地说,1 天/24 小时 * 6 小时),下午 6:00 将是 0.75。那么,最简​​单的过滤方法是:

// 6 hours after midnight
Frac(YourTimeField.AsFloat) >= (1.0 / 24.0) * 6 and
// 18 hours after midnight
Frac(YourTimeField.AsFloat) <= (1.0 / 24.0) * 18; 

进行实际计算可确保如果数字不能精确地表示为 0.25(如 0.2499999999999),您仍然可以得到正确的值进行比较。

Frac 返回小数部分,只是为了使代码清楚地表明您只考虑值的时间部分。

【讨论】:

  • 我知道它可以作为可执行代码工作,但我可以在数据集的过滤字符串中使用 Fract 函数吗?
  • 没有。您可以在 OnFilterRecord 事件中使用它。你用的是什么数据库?可能有比过滤更好的方法。
  • 我实际上在使用 kbmMemData
【解决方案3】:

我不使用ADO,而是使用Zeos,但渲染为浮动

  xx.filter:='datefieldname > '+floattostr(strtodatetime(edit1.text));

为我工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多