문제

사용자가 프로그램에서 DateTime 필드의 형식을 수동으로 입력 할 수 있기를 원합니다. 나는 테디 구성 요소가 있습니다. 예를 들어 사용자가 'HH : NN'을 입력하면 유효한 DateTime 형식 문자열이며 모든 DateTime 구성 요소는 형식 속성을 변경해야하지만 'ASD'를 입력하면 그렇지 않습니다. 내 기능을 쓰지 않고 이것을 확인하는 빠른 방법이 있습니까?

도움이 되었습니까?

해결책

함수를 사용할 수 있습니다.

TryStrToDate
TryStrToTime
TryStrToDateTime

그들은 문자열을 날짜/시간으로 변환하려고 시도하고 변환이 성공하면 true가 반환됩니다. 따라서 예외가 제기되지 않습니다.

옵션 Tformatsettings 매개 변수를 사용하여 자신의 형식을 정의 할 수 있습니다.

모든 기능은 sysutils에서 정의됩니다.

그러나 TDATETIMEPICTOR 및 TMONTHCALENDAR와 같은 VCL에는 몇 가지 날짜/시간 컨트롤이 있습니다. 당신은 그것들도 사용할 수 있습니다.

다른 팁

문제는 '유효한 형식'을 어떻게 정의합니까? 아마도 당신이 할 수있는 최선은 형식 문자열의 특정 문자의 존재를 검색하는 것입니다. 그러나 사용자가 해를 보는 것에 관심이 없거나 시간을보고 싶지 않다면 어떻게해야합니까?

나는 그들이 '유효한 형식'을 입력했는지 확인하는 것에 대해 너무 많이 강조하지 않을 것입니다. 오히려 현재 날짜 시간을 사용하여 입력 한 형식의 미리보기를 제공하십시오.

편집하다: OP에서 새 정보를위한 업데이트

질문에 대한 약간의 설명이있었습니다.

실제로 데이터베이스에서 TDATETIMEPICTER 및 TDATETIME 필드의 형식 속성을 지정해야합니다. 그리고 사용자가 이러한 형식을 변경할 수 있기를 바랍니다. - Tofig Hasanov

그것은 중요한 설명 일 것입니다. 아마도 당신은 당신의 질문에 그것을 포함시키고 싶습니까?

중요한 것은 형식 문자열이 디스플레이 형식뿐만 아니라 편집 형식도 표시한다는 것입니다. 이제 거의 모든 문자열이 유효하지만 모두가 특히 유용하지는 않습니다 (특히 편집에). 예 :

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

이것은 당신의 날짜가 할 수 있습니다 그에 따라 포맷되었습니다. 그러나 달을 설정하는 데 특히 유용하지 않습니다.

이제 IMHO, 사용자가 자신의 형식 문자열에 월 필드를 포함하지 않음으로써 자신의 삶을 어렵게 만들고 싶다면! 그러나 문제는 형식 규칙이 약간 기술적이며 사용자는 몇 달과 몇 분이 혼합 될 수 있다는 점에서 발생합니다. 예를 들어 FTimeFormat := 'HH:MM:SS' 실제로u003Chours> :> :u003Cseconds>

그럼에도 불구하고, 나는 원래의 제안을지지합니다 (하나의 사소한 조정과 함께) : 오히려 그들이 입력 한 형식의 미리보기를 제공합니다. 현재 날짜 시간 형식 문자열에서 '실수'를 강조 해야하는 미리 정해진 날짜 시간.

사용자 가이 설정을 정의 할 수있는 구성 대화 상자가 있다고 가정합니다.

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

경고

당신은 이것을 둘 다 사용하고 싶다고 언급했습니다 TDateTimeField 그리고 TDateTimePicker. 안타깝게도, TDateTimePicker 형식을 사용하지 않는 내장 된 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');

trystrtodatetimevar로 전달할 myDateTimevar 변수를 설정하지 않고 확인하려면 예외 처리 만 사용할 수 있습니다.

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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top