Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Проблемы и решения при конвертации строки в формате yyyymmddhhnnss в TDateTime в Delphi

Delphi , Синтаксис , Дата и Время

 

В процессе работы с Delphi иногда возникает необходимость обрабатывать строки, содержащие дату и время в нестандартном формате, например, в виде yyyymmddhhnnss. В Delphi для работы с датой и временем используется тип TDateTime, который представляет собой число, где целая часть — количество дней с 30 декабря 1899 года, а дробная часть — доля дня (от 0 до 1).

Проблема заключается в том, что стандартные функции Delphi, такие как StrToDateTime(), требуют наличия разделителей между различными компонентами даты и времени (например, -, :, ). Однако, если у вас есть строка в формате yyyymmddhhnnss без разделителей, то использование StrToDateTime() становится затруднительным.

В этой статье мы рассмотрим несколько способов решения этой проблемы, включая написание собственной функции для парсинга строки, а также использование вспомогательных функций для корректного конвертинга.

Решение 1: Написание собственной функции для парсинга строки

Наиболее надежным и универсальным способом является написание собственной функции для парсинга строки в формате yyyymmddhhnnss. Это позволяет точно контролировать процесс конвертации и убедиться, что все значения находятся в допустимых диапазонах.

Вот пример такой функции:

uses
  Math, DateUtils;

function TryMyStringToDateTime(const S: string; out ADateTime: TDateTime): Boolean;
begin
  if S.Length <> 14 then
    Exit(False);

  var LYearStr := Copy(S, 1, 4);
  var LMonthStr := Copy(S, 5, 2);
  var LDayStr := Copy(S, 7, 2);
  var LHourStr := Copy(S, 9, 2);
  var LMinuteStr := Copy(S, 11, 2);
  var LSecondStr := Copy(S, 13, 2);

  var LYear, LMonth, LDay, LHour, LMinute, LSecond: Integer;
  if
    not
      (
        TryStrToInt(LYearStr, LYear)
        and TryStrToInt(LMonthStr, LMonth)
        and TryStrToInt(LDayStr, LDay)
        and TryStrToInt(LHourStr, LHour)
        and TryStrToInt(LMinuteStr, LMinute)
        and TryStrToInt(LSecondStr, LSecond)
      )
  then
    Exit(False);

  if not InRange(LYear, 1, 9999) then
    Exit(False);

  if not InRange(LMonth, 1, 12) then
    Exit(False);

  if not InRange(LDay, 1, DaysInAMonth(LYear, LMonth)) then
    Exit(False);

  if not InRange(LHour, 0, 23) then
    Exit(False);

  if not InRange(LMinute, 0, 59) then
    Exit(False);

  if not InRange(LSecond, 0, 59) then
    Exit(False);

  ADateTime := EncodeDateTime(LYear, LMonth, LDay, LHour, LMinute, LSecond, 0);
  Result := True;
end;

function MyStringToDateTime(const S: string): TDateTime;
begin
  if not TryMyStringToDateTime(S, Result) then
    raise EConvertError.CreateFmt('Invalid datetime string: "%s"', [S]);
end;

function MyStringToDateTimeDef(const S: string; const ADefault: TDateTime): TDateTime;
begin
  if not TryMyStringToDateTime(S, Result) then
    Result := ADefault;
end;

Объяснение кода:

  1. TryMyStringToDateTime: Эта функция пытается преобразовать строку в TDateTime. Она проверяет длину строки и разбивает её на компоненты даты и времени. Затем она проверяет, что все значения находятся в допустимых диапазонах. Если все проверки проходят успешно, она использует функцию EncodeDateTime для создания TDateTime.

  2. MyStringToDateTime: Эта функция вызывает TryMyStringToDateTime. Если преобразование неудачно, она генерирует исключение EConvertError.

  3. MyStringToDateTimeDef: Эта функция также вызывает TryMyStringToDateTime. Если преобразование неудачно, она возвращает значение по умолчанию.

Решение 2: Использование вспомогательных функций для добавления разделителей

Если вам не нужно полностью контролировать процесс парсинга, вы можете использовать вспомогательные функции для добавления разделителей в строке, чтобы сделать её подходящей для использования с StrToDateTime.

Вот пример такой функции:

function MyDateTimeFromString(MyString: string): TDateTime;
var
  Fs: TFormatSettings;
begin
  Insert('-', MyString, 5); // Добавляем разделитель между годом и месяцем
  Insert('-', MyString, 8); // Добавляем разделитель между месяцем и днем
  Insert(' ', MyString, 11); // Добавляем разделитель между днем и временем
  Insert(':', MyString, 14); // Добавляем разделитель между часами и минутами
  Insert(':', MyString, 17); // Добавляем разделитель между минутами и секундами

  Fs := TFormatSettings.Create;
  Fs.DateSeparator := '-';
  Fs.TimeSeparator := ':';
  Fs.ShortDateFormat := 'yyyy-mm-dd';
  Fs.ShortTimeFormat := 'hh:nn:ss';

  Result := StrToDateTime(MyString, Fs);
end;

Объяснение кода:

  1. Insert: Эта функция добавляет разделители в строку. Мы добавляем - между годом и месяцем, - между месяцем и днем, между днем и временем, : между часами и минутами, и : между минутами и секундами.

  2. TFormatSettings: Мы создаем экземпляр TFormatSettings и настраиваем его для использования - как разделителя даты и : как разделителя времени.

  3. StrToDateTime: Наконец, мы используем StrToDateTime с нашими настроенными TFormatSettings для преобразования строки в TDateTime.

Вывод

Оба решения имеют свои преимущества и недостатки. Если вам нужно полный контроль над процессом парсинга и убедиться, что все значения находятся в допустимых диапазонах, то лучше использовать первое решение — написание собственной функции для парсинга строки. Если вам нужен более простой и быстрый способ, который работает в большинстве случаев, то можно использовать второе решение — добавление разделителей в строку и использование StrToDateTime.

В Delphi 11 Alexandria, как и в предыдущих версиях, нет встроенной функции для парсинга строк в формате yyyymmddhhnnss без разделителей. Поэтому использование собственных функций остаётся наиболее надежным и универсальным способом решения этой проблемы.

Создано по материалам из источника по ссылке.

В статье рассматриваются способы преобразования строки в формате yyyymmddhhnnss в тип TDateTime в Delphi, когда стандартные функции не справляются из-за отсутствия разделителей.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Дата и Время ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 14:44:46/0.0035128593444824/0