如何从TDateTimePicker

时间:2017-03-23 09:34:51

标签: delphi datetime datetimepicker datetime-format delphi-xe7

我真的很困惑。我想做的事情(看起来非常简单)是在TDateTimePicker中显示日期+时间,并集成日历,并且能够在其值发生变化后读取它。

我想使用dd / MM / yyyy hh:mm格式。

由于TDateTimePicker不是TDateOrTimePicker,因此使用的是:

  • 种类:dtkDate(显示日历)
  • 格式:' dd / MM / yyyy hh:mm'

看起来不错,现在让我们读一下:

showmessage(DateTimeToStr(DateTimePicker1.Date)); 

仅正确显示日期。不考虑hh:mm部分的变化。我总是得到默认值。 然后我想:还有一个Time属性,也许我需要读取2次的值。

 showmessage(DateTimeToStr(DateTimePicker1.Time));
 showmessage(DateTimeToStr(DateTimePicker1.Date));

但我有与以前完全相同的输出(和问题)。现在,让我们尝试将此Kind属性更改为dtkTime,然后读取时间,然后将其切换回dtkDate,然后读取日期。

但不,它仍然无法奏效。将Kind属性从dtkDate切换到dtkTime会删除我在hh:mm部分的输入。

我知道我实际上应该使用2个TDateTimePickers:一个用于日期,一个用于时间。

所以我的问题是:

  • 有一种简单的方法可以解决我简单而常见的问题(a 真的是DateTimePicker)?

Delphi设计问题:

  • 为什么Format属性基本上没用? 误导?拥有TimeFormat,DateFormat和正确的格式 验证过程并不难。

请注意,我发布这个问题主要是为了避免初学者做同样的调试和挫折的过程。

4 个答案:

答案 0 :(得分:6)

  

我想做的事情(看起来非常简单)是在TDateTimePicker中显示日期+时间,并集成日历,并且能够在其值发生变化后读取它。

     

我想使用dd / MM / yyyy hh:mm格式

抱歉,但你不能。 TDateTimePicker仅适用于日期或时间,但不能同时使用。

如果将Kind属性设置为dtkDate,则可以指定自定义DATE格式,但忽略任何TIME格式,并且使用Time属性未定义。

如果将Kind属性设置为dtkTime,则可以指定自定义TIME格式,但忽略任何DATE格式,并且使用Date属性未定义。

读取Date属性时,只有值的DATE部分有效。在一个完美的世界中,TIME部分将始终为零,但我看到它有时会包含垃圾。但是,您可以使用DateUtils.DateOf()函数轻松忽略它:

Value := DateOf(DateTimePicker1.Date);

Time属性和值的DATE部分相同。您可以使用DateUtils.TimeOf()函数忽略任何潜在的垃圾:

Value := TimeOf(DateTimePicker1.Time);
  

有没有一种简单的方法可以解决我的简单和非常常见的问题(一个真正的DateTimePicker)?

使用TDateTimePicker的唯一真正解决方案是使用两个单独的TDateTimePicker控件,一个用于日期,另一个用于日期。您可以在需要时将两个值组合在一起:

Value := DateOf(DateTimePicker1.Date) + TimeOf(DateTimePicker2.Time)

如果您想显示TDateTime,请执行相反的操作:

DateTimePicker1.Date := DateOf(Value);
DateTimePicker2.Time := TimeOf(Value);

否则,找到支持您需要的第三方选择器(或编写自己的选择器)。

  

为什么Format属性基本上没用且误导?

这不是无用和误导。它非常有用,但仅限于当前Kind设置的范围内。

  

拥有TimeFormat,DateFormat和正确的格式验证过程并不难。

TDateTimePicker只是Win32 Date and Time Picker control的一个瘦包装器,它没有这样的功能。当然,他们可以编写自定义逻辑,以允许在保留不同设置的Kind值之间切换,但实际上并不是如何使用DTP控件。您设置Kind一次,Format一次,然后根据需要处理输入和输出。不来回切换。仅仅因为你可以动态切换Kind并不意味着应该。如果您认为编写这样的自定义逻辑很容易,欢迎您使用自己的代码。

答案 1 :(得分:1)

这些天我遇到了同样令人沮丧的问题。但在我的情况下,我只需要从TDateTimePicker字段中获取完整的日期和时间(不需要以编程方式设置它,但这不是很困难)。所以我做的是创建我自己的TDateTimePicker并创建一个新的公共属性,获取字段Caption并设置为DateTime(Caption受documentation保护。这是我的代码:

unit uZDateTimePicker;

interface

uses
 Vcl.ComCtrls, SysUtils;

type
  TZDateTimePicker = class(TDateTimePicker)
  private
    procedure SetDateAndTime;

  protected
    procedure Change; override;

  end;

implementation

{ TZDateTimePicker }

procedure TZDateTimePicker.Change;
begin
  SetDateAndTime
end;

procedure TZDateTimePicker.SetDateAndTime;
begin
  DateTime := StrToDateTime(Caption);
  inherited;
end;


end.

就这么简单。

此外,如果您使用DevExpress组件,您将使用可以正常工作的TcxDateEdit。

答案 2 :(得分:1)

我有完全相同的问题。 安德烈解决方案的作用就像安德烈的魅力一样。

问题:我们需要创建一个新单元,创建一个新组件并将组件注册到另一个包,以便能够在设计时设置表单。

解决方案:为了避免这种情况,只需在您使用TDateTimePicker组件的表单中声明以下类:THackDateTimePicker

...
type
  // this class is just to access protected Caption property
  THackDateTimePicker = class(TDateTimePicker);

  TSymbolInfoForm = class(TForm)
  ...
end;

然后只需实现OnChange事件:

procedure TSymbolInfoForm.dtpChange(Sender: TObject);
begin
   TDatetimePicker(Sender).Datetime := StrToDateTime(THackDateTimePicker(Sender).Caption);
end;

您可以将同一表单上所有TDateTimePicker组件的所有OnChange事件链接到理智的OnChange事件......瞧!

答案 3 :(得分:-1)

以上答案都是正确的,您可以从datetimepicker.DateTime属性中获取datetime,也可以通过将“ Format”属性设置为dd / MM / yyyy hh:mm来显示日期和时间