views:

758

answers:

4

I want user to be able to manually enter format of the datetime fields in the program. I have Tedit component. For example if user enters 'HH:nn', then this is a valid datetime format string and all datetime components should change format property to this, but if he enters 'asd', it is not. Is there a quick way to check this, without writing my own function?

+8  A: 

You could use the functions:

TryStrToDate
TryStrToTime
TryStrToDateTime

They try to convert a string to a date/time and if the conversion succeeds, it returns true. So there are no exceptions raised.

You can use the optional TFormatSettings parameter to define your own format.

All functions are defined in SysUtils.

But there are some date/time controls available in the VCL like TDateTimePicker and TMonthCalendar. You can use them also.

Gamecat
My question was different, I don't need to check if the string is a valid DateTime, I need to see if the string is a valid DateTime format (Ex: "dd.MM.yy HH.mm" is a valid DateTime Format, while "KK.LL.MM NN.RR" is not.
Tofig Hasanov
Yes, you can use the function for that purpose. You can tweak the format settings.
Gamecat
+4  A: 

The problem is, how do you define a 'valid format'? Possibly, the best you could do is search for the existence of specific letters in the format string. But what if the user doesn't care about seeing the year, or doesn't want to see the time?

I wouldn't stress too much about verifying that they have entered a 'valid format'. Rather just give them a preview of the format they've entered using the current date-time.

Edit: Update for new info from OP

There was a little clarification on the question:

Actually I need to specify Format property of TDateTimePicker and TDateTime fields in Database. And I want user to be able to change these formats. – Tofig Hasanov

That's an important clarification, perhaps you want to include it in your question?

The important thing is that the format string will not only indicate the Display Format, but also the editing format. Now although pretty much any string is valid, not all are particularly useful (especially for editing). E.g.:

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

This is perfectly valid in the sense that your date can be formatted accordingly. However, it is not particularly useful for setting the month.

Now IMHO, if a user wants to make make their lives difficult by not including month fields in their format string - tough! The problem however comes in that the format rules are a little technical, and a user may get months and minutes mixed up. E.g. FTimeFormat := 'HH:MM:SS' which is actually <hours>:<months>:<seconds>

Even so, I stand by my original suggestion (with one minor tweak): Rather just give them a preview of the format they've entered using the current date-time a predetermined date-time that should emphasise 'mistakes' in the format string.

Assuming you have a configuration dialog in which you intend letting the user define this setting:

  • Add a TComboBox (you can then 'pre-load' it with sample strings to guide the user; also they may simply choose one of your already suitable options.
  • Add a label in which you illustrate the sample behaviour of the chosen format string.
  • Implement TComboBox.OnChange to illustrate the effect of the user's choice.

The following code should do the trick:

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;

WARNING

You mentioned you want to use this for both TDateTimeField and TDateTimePicker. Unfortunately, TDateTimePicker simply wraps a built-in Windows Control which does not use FormatDateTime, and consequently also has different rules for its format strings.

So I'm afraid you'll have to allow your users to configure two different format strings. :(

Craig Young
Indeed, +1. Everything that isn't a valid placeholder would remain as-is. Coupled with a list of valid placeholders this would allow the user to iteratively change the format until they're satisfied. If you flesh out your answer (maybe with some code sample) I'd like to see it accepted.
mghie
+1  A: 

To expand on Gamecat's answer

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

If you just want to check it without setting up the MyDateTimeVar variable to pass to tryStrToDateTimeVar you can just use exception handling

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

Doug and Gamecat, I believe you are both misunderstanding the question.

  • He doesn't want to go from a string to a date.
  • He has the date.
  • He wants to convert that date into a string according to a format specified by the user.
  • I.e. DisplayDate := FormatDateTime(UserDefinedFormat, Now());

The only thing that StrToDateTime (or TryStrToDateTime) could be used for is to attempt a circular 'consistency check'. But that would be no good, because there is no guarantee the user wants to see all elements of the date/time. Consequently the circular check cannot work!

Craig Young
Actually I need to specify Format property of TDateTimePicker and TDateTime fields in Database. And I want user to be able to change these formats.
Tofig Hasanov
That's pretty much the same thing: If you set the DisplayFormat property of a TDateTimeField then that will result in calls to FormatDateTime as needed.The point in my other answer is that pretty much any string is **valid**, although not all are **useful**.However... your mention of TDateTimePicker does throw a big spanner in the works.... The format string for TDateTimeField and TDateTimePicker use different conventions, so they're not interchangeable!
Craig Young