簡體   English   中英

如何在Delphi中檢查字符串是否是有效的DateTime格式字符串

[英]How to check if string is a valid DateTime Format string in Delphi

我希望用戶能夠在程序中手動輸入日期時間字段的格式。 我有Tedit組件。 例如,如果用戶輸入'HH:nn',那么這是一個有效的日期時間格式字符串,並且所有日期時間組件都應該將format屬性更改為this,但如果他輸入'asd',則不是。 有沒有快速的方法來檢查這一點,而無需編寫自己的功能?

你可以使用這些功能:

TryStrToDate
TryStrToTime
TryStrToDateTime

他們嘗試將字符串轉換為日期/時間,如果轉換成功,則返回true。 所以沒有例外。

您可以使用可選的TFormatSettings參數來定義自己的格式。

所有功能都在SysUtils中定義。

但是VCL中有一些日期/時間控件可用,如TDateTimePicker和TMonthCalendar。 你也可以使用它們。

問題是,你如何定義'有效格式'? 可能,您可以做的最好的事情是在格式字符串中搜索特定字母的存在。 但是,如果用戶不關心看到年份,或者不想看時間怎么辦?

我不會過分強調驗證他們已經輸入了“有效格式”。 而只是讓他們使用當前日期時間預覽他們輸入的格式。

編輯 :從OP更新新信息

對這個問題有一點澄清:

實際上我需要在Database中指定TDateTimePicker和TDateTime字段的Format屬性。 我希望用戶能夠更改這些格式。 - Tofig Hasanov

這是一個重要的澄清,也許你想把它包含在你的問題中?

重要的是格式字符串不僅會指示顯示格式,還會指示編輯格式。 現在雖然幾乎任何字符串都是有效的,但並非所有字符串都特別有用(特別是對於編輯)。 例如:

FDateTimeFormat := '"The day is "d" of this month of the year "yy';

這是完全有效的,因為您的日期可以相應地格式化。 但是,它對於設置月份並不是特別有用。

現在恕我直言,如果用戶想要通過不在其格式字符串中包含月份字段來使他們的生活變得困難 - 艱難! 然而問題在於格式規則有點技術性,用戶可能會混淆幾個月和幾分鍾。 例如FTimeFormat := 'HH:MM:SS'實際上是<hours>:< months >:<seconds>

即便如此,我堅持我的原始建議(只需一個小調整):而是讓他們使用 當前日期時間 預覽他們輸入的格式預定的日期時間應該強調格式字符串中的“錯誤” 。

假設您有一個配置對話框,您打算讓用戶定義此設置:

  • 添加一個TComboBox(然后你可以用樣本字符串'預加載'來引導用戶;他們也可以選擇一個你已經合適的選項。
  • 添加一個標簽,在其中說明所選格式字符串的示例行為。
  • 實現TComboBox.OnChange以說明用戶選擇的效果。

以下代碼應該可以解決問題:

procedure TConfigDialog.DateTimeFormatChange(Sender: TObject);
var
  LCheckDate: TDateTime;
  LFormattedDate: String;
begin
  LCheckDate := EncodeDate(1999, 12, 31) + EncodeTime(20, 45, 50, 123);
  LFormattedDate := FormatDateTime(DateTimeFormat.Text, LCheckDate);
  DateFormatSample.Caption := 'Fri 31 December 1999 at 8:45:50.123 would be displayed as: ' + LFormattedDate;
end;

警告

您提到要將其用於TDateTimeFieldTDateTimePicker 不幸的是, TDateTimePicker只包含一個不使用FormatDateTime的內置Windows控件,因此對其格式字符串也有不同的規則。

所以我擔心你必須允許你的用戶配置兩個不同的格式字符串。 :(

擴展Gamecat的答案

If not tryStrToDateTime(Edit1.text,MyDateTimeVar) then
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');

如果您只想檢查它而不設置MyDateTimeVar變量以傳遞給tryStrToDateTimeVar,您可以只使用異常處理

try
StrToDateTime(Edit1.Text);
except
ShowMessage('You need to make your entry look like a date...how about yy/mm/dd');
end;

Doug和Gamecat,我相信你們都誤解了這個問題。

  • 他不想從一個字符串到一個約會。
  • 他有約會。
  • 他希望根據用戶指定的格式將該日期轉換為字符串。
  • DisplayDate := FormatDateTime(UserDefinedFormat, Now());

該StrToDateTime(或TryStrToDateTime) 用於的唯一事情是試圖圓形“一致性檢查”。 但這並不好,因為無法保證用戶想要查看日期/時間的所有元素。 因此,循環檢查不起作用!

function to_date(p_format,p_string:string): TDateTime;
var
  v_day,           //dd
  v_month,         //mm
  v_year:Integer;  //yyyy
  v_hour,          //hh
  v_minute,        //nn
  v_second:Integer;//ss

  v_date:TDateTime;
  v_time:TDateTime;
begin
  v_day:=Pos('dd',p_format);
  v_month:=Pos('mm',p_format);
  v_year:=Pos('yyyy',p_format);

  v_hour:=Pos('hh',p_format);
  v_minute:=Pos('nn',p_format);
  v_second:=Pos('ss',p_format);

  v_day:=StrToInt(Copy(p_string,v_day,2));
  v_month:=StrToInt(Copy(p_string,v_month,2));
  v_year:=StrToInt(Copy(p_string,v_year,4));

  v_hour:=StrToInt(Copy(p_string,v_hour,2));
  v_minute:=StrToInt(Copy(p_string,v_minute,2));
  v_second:=StrToInt(Copy(p_string,v_second,2));

  v_date:=EncodeDate(v_year,v_month,v_day);
  v_time:=EncodeTime(v_hour,v_minute,v_second,0);
  ReplaceTime(v_date,v_time);
  Result:=v_date;
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM