Как проверить, является ли строка допустимой строкой формата DateTime в Delphi

StackOverflow https://stackoverflow.com/questions/1846446

Вопрос

Я хочу, чтобы пользователь мог вручную вводить формат полей даты и времени в программе.У меня есть компонент Tedit.Например, если пользователь вводит «ЧЧ: nn», то это допустимая строка формата даты и времени, и все компоненты даты и времени должны изменить на нее свойство формата, но если он вводит «asd», это не так.Есть ли быстрый способ проверить это, не написав собственную функцию?

Это было полезно?

Решение

Вы можете использовать функции:

TryStrToDate
TryStrToTime
TryStrToDateTime

Они пытаются преобразовать строку в дату/время, и если преобразование завершается успешно, возвращается true.Так что никаких исключений не предусмотрено.

Вы можете использовать дополнительный параметр TFormatSettings, чтобы определить свой собственный формат.

Все функции определены в SysUtils.

Но в VCL доступны некоторые элементы управления датой и временем, такие как TDateTimePicker и TMonthCalendar.Вы также можете использовать их.

Другие советы

Проблема в том, как определить «действительный формат»?Возможно, лучшее, что вы можете сделать, — это поискать наличие определенных букв в строке формата.Но что, если пользователя не интересует год или он не хочет видеть время?

Я бы не стал слишком беспокоиться о проверке того, что они ввели «действительный формат».Лучше просто дайте им предварительный просмотр формата, который они ввели, используя текущую дату и время.

Редактировать:Обновление новой информации от ОП

По вопросу было небольшое уточнение:

На самом деле мне нужно указать свойство Format полей TDateTimePicker и TDateTime в базе данных.И я хочу, чтобы пользователь мог изменять эти форматы.— Тофиг Гасанов

Это важное уточнение, возможно, вы захотите включить его в свой вопрос?

Важно то, что строка формата будет указывать не только формат отображения, но и формат редактирования.Хотя практически любая строка действительна, не все из них особенно полезны (особенно для редактирования).Например.:

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

Это совершенно справедливо в том смысле, что ваше свидание возможно отформатирован соответствующим образом.Однако для установки месяца это не особенно полезно.

ИМХО, если пользователь хочет усложнить себе жизнь, не включая поля месяца в строку формата - это сложно!Однако проблема заключается в том, что правила формата немного технические, и пользователь может перепутать месяцы и минуты.Например. FTimeFormat := 'HH:MM:SS' что на самом деле составляет <часы>:<месяцы>:<секунды>

Несмотря на это, я придерживаюсь своего первоначального предложения (с одной незначительной поправкой):Лучше просто дайте им предварительный просмотр формата, который они ввели, используя текущая дата-время заранее определенная дата и время, которая должна подчеркнуть «ошибки» в строке формата.

Предположим, у вас есть диалоговое окно конфигурации, в котором вы намерены позволить пользователю определить этот параметр:

  • Добавьте 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, который не использует FormatDateTime и, следовательно, также имеет другие правила для своих строк формата.

Поэтому я боюсь, что вам придется разрешить пользователям настраивать две разные строки формата.:(

Чтобы расширить ответ 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;

Дуг и 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