powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Перевести string в DateTime
25 сообщений из 33, страница 1 из 2
Перевести string в DateTime
    #39780927
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите пожалуйста, какой самый простой способ перевести string в TDateTime с нужным мне форматом?
Я хочу сделать так, что компьютер разбирался с форматом даты, а не я.

Только без возьни с TFormatSetting - это явно бред.
Что-то типа такого.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
var 
 ADate:TDateTime;
begin
 if not ConvertToDate(s,ADate, 'YYYY-MM-DD') then
 if not ConvertToDate(s,ADate, 'YYYY.MM.DD') then
 if not ConvertToDate(s,ADate, 'MM-DD-YYYY') then
и т.д.
end;
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780934
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_B,

ну, всё правильно, и т.д. Т.е. еще несколько десятков вариантов. И молиться при этом, чтобы
01.02.2019 интерпретировалась как 'MM-DD-YYYY', а не как 'DD-MM-YYYY' или наоборот.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780948
Barlone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так:
- а 01.02.2019 это второе января ли первое февраля?
- а я откуда знаю, компьютер умнее, он должен сам разобраться...
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780951
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone- а 01.02.2019 это второе января ли первое февраля?
Да там и повеселее могут быть ситуации...

Например, 12.12.12
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780953
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanBarlone- а 01.02.2019 это второе января ли первое февраля?
Да там и повеселее могут быть ситуации...

Например, 12.12.12
Хотя...
в этом случае как раз супер-умный алгоритм не сможет ошибиться.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780965
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
function TForm7.StrToDateFrmt(const iFormat, iDateStr: string): TDateTime;
var
  AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word;
  aPos: Integer;

  procedure InitVars;
  begin
    AYear := 1;
    AMonth := 1;
    ADay := 1;
    AHour := 0;
    AMinute := 0;
    ASecond := 0;
    AMilliSecond := 0;
  end;

  function GetPart(const iPart: Char): Word;
  var
    aYCnt: Integer;
  begin
    Result := 0;
    aYCnt := 0;

    while (aPos <= High(iFormat)) and (iFormat.Chars[aPos + aYCnt] = iPart) do
      inc(aYCnt);

    Result := StrToInt(iDateStr.Substring(aPos, aYCnt));

    aPos := aPos + aYCnt;
  end;

begin
  InitVars;
  aPos := 0;

  while aPos <= High(iFormat) do
  begin
    case iFormat.Chars[aPos] of
      'Y':
        AYear := GetPart('Y');
      'M':
        AMonth := GetPart('M');
      'D':
        ADay := GetPart('D');
      'H':
        AHour := GetPart('H');
      'N':
        AMinute := GetPart('N');
      'S':
        ASecond := GetPart('S');
      'Z':
        AMilliSecond := GetPart('Z');
    else
      inc(aPos);
    end;
  end;

  Result := EncodeDateTime(AYear, AMonth, ADay, AHour, AMinute, ASecond,
    AMilliSecond);
end;
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780967
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Год отличить от не года - это не сложно, а с остальным сложнее.

Я как-то пробовал сделать алгоритм более менее универсальным и он даже иногда правильно выуживает даты, но временами не работает. Любые идеи по улучшению горячо приветствуются:

Те, кто не любит корявый код - не смотрите :-)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
// функцию RegExp сам напишешь 
function RegExp(const Pattern, SMatch: string): string;

function ExtractDate(const Text: string): TDateTime;
var
  Pattern: string;
  s, d, m, y: string;
  YY, MM, DD: word;
  k: integer;
const
  MonthNames: string = 'jan feb mar apr may jun jul aug sep oct nov dec';
begin
  result := 0;
  Pattern := '(\d{4}\s[A-Za-z]{3,8}\s\d{1,2}|\d{1,2}\s[A-Za-z]{3,8}\s\d{4}|\d{4}[-\.\/]\d{1,2}[-\.\/]\d{1,2}|\d{1,2}[-\.\/]\d{1,2}[-\.\/]\d{4})';
  s := RegExp(Pattern, Text);
  if s <> '' then
  begin
    // extract year
    y := RegExp('(\d{4})', s);
    if y <> '' then
      YY := StrToInt(y)
    else
      exit;

    Pattern := '([a-zA-Z]+)';
    m := RegExp(Pattern, s);
    if m <> '' then
    begin
      // month as a word
      MM := pos(lowercase(copy(m, 1, 3)), MonthNames);
      if MM = 0 then
        exit;
      MM := (MM - 1) div 4 + 1;
      s := RegExp('(?<!\d)(\d{1,2})(?!\d)', s);
      if s = '' then
        exit;
      DD := StrToInt(s);
    end
    else
    begin
      // only numbers

      // get date and month
      s := RegExp('(?<!\d)(\d{1,2})(?!\d)', s);
      if s = '' then
        exit;
      k := pos(#13#10, s);
      if k = 0 then
        exit;

      D := copy(s, 1, k - 1);
      M := copy(s, k + 2, 255);

      dd := StrToInt(D);
      mm := StrToInt(M);
      // check if the date is in a sort of range
      if (not (dd in [1..12])) and (not(mm in [1..12]))   then
        exit;

      // try to guess by number what is what
      if dd > 12 then
      begin
        // this is a date
      end
      else
      if mm > 12 then
      begin
        // this is not a month

        // exchange day and month
        k := DD;
        DD := MM;
        MM := k;

      end
      else
      begin
        // check position of a year (first or last)
        if pos(y, s) > 4 then
        begin
          // year is in the end

          if Length(D) = 1 then
          begin
            // probably this is an american way of coding date
            // exchange day and month
            k := DD;
            DD := MM;
            MM := k;
          end;

        end
        else
        begin
          // year is in the beginning

          // exchange day and month
          k := DD;
          DD := MM;
          MM := k;
        end;
      end;
    end;
    if (DD in [1..31]) and (MM in [1..12]) then
    begin
      if not TryEncodeDate(YY, MM, DD, result) then
        result := 0;
    end;
  end;
end;

...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780975
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanwadmanпропущено...

Да там и повеселее могут быть ситуации...

Например, 12.12.12
Хотя...
в этом случае как раз супер-умный алгоритм не сможет ошибиться.
Да ну. год 0012, 1912, 2012...
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780982
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BarloneКак-то так:
- а 01.02.2019 это второе января ли первое февраля?
- а я откуда знаю, компьютер умнее, он должен сам разобраться...
"Программа сама должна знать, что нужно, а что не нужно".

В общем-то, такая программа давно написана.
http://button.dekel.ru/
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39780995
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я делал ф-цию, на вход кот. передавал разбираемую строку и вероятный формат (ГМД, ДМГ, МДГ)
Любое нечисло это разделитель.
Бил строку на части, проверял на ошибки (мес 1..12, день 1..31), год подгонял до тысяч, если он короткий.
Потом из частей получал дату-время.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781006
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Barlone - а 01.02.2019 это второе января ли первое февраля?

А ты сам-то можешь однозначно ответить на этот вопрос ? Подозреваю - что нет.
Точно так же, поступит и компьютер.
Первое с чего должна начинаться конвертация - это с локального формата времени.
Если она не получилась, пусть дальше работает.

Мне ну совсем не хочется разбираться, какой разделитель стоит "-", "." или даже ",".
Также, если первым или последним идёт число "2019" (т.е. "четырёхзначное")
Думаю, что 8 ядерный CoreI7 в состоянии сам разобраться ?
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781009
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, строки могут ещё иметь и такой формат +-:
автор2019-03-01T00:00:00.000000
2019-03-01T10:59:16.657Z
2019-03-01T10:59:16.657Z +03
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781010
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_B
Код: pascal
1.
ConvertToDate(s,ADate, 'YYYY-MM-DD')



функция sscanf ?
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781016
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BМне ну совсем не хочется разбираться, какой разделитель стоит "-", "." или даже ",".

Наверное, надо делать так.
Осталось только с форматом определится...
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
function ConvertToDate(const DateStr:string):TDateTime;
var
 s:string;
begin
 s:=StringReplace(DateStr,',','.');
 s:=StringReplace(s,'-','.');
 s:=StringReplace(s,' ','.');
 s:=StringReplace(s,'_','.');
//т.е. все возможные разделители сначала привести к одному.
end;
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781017
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ariochфункция sscanf ?

автор[Error] Unit1.pas(27): Undeclared identifier: 'sscanf'
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781025
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_BДумаю, что 8 ядерный CoreI7 в состоянии сам разобраться ?
Если-б он мог, то была-бы тема?
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781038
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimonka, "если у вас есть проблема и вы собираетесь решить ее регулярными выражениями – теперь у вас две проблемы" (С)
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781059
Фотография Dimonka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vavanDimonka, "если у вас есть проблема и вы собираетесь решить ее регулярными выражениями – теперь у вас две проблемы" (С) Третья проблема была в том, что это всё делалось в PascalScript :-) Так что проблем было куда больше.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781063
GunSmoker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valery_B, ты бы озвучил откуда ты получаешь строки. Если их вводит пользователь, то не надо вообще пробовать что-то иное окромя локального формата даты.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781067
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GunSmoker,

В контролы Edit/DateEdit должен безпроблемно вставляться текст(CTRL+V).
От куда берётся(CTRL+C) - неизвестно. Пусть из Excel
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781072
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На самом деле, в реальности всего получается только 2 формата даты:
1. Общепринятый - DD MM YYYY
2. Компьютерный - YYYY MM DD

01.02.2019 - это 01 Февраля 2019г.

Видимо, надо будет создать 2 FormatSettings с разными форматами дат.
Разделители, привести к чему-то единому через StringReplace.
Всё остальное скорее всего будет не дата.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781079
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Valery_B,

А вот Америка пишет - MM/DD/YYYY
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781082
MirnyiAtom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я бы делал так:
регулярным выражением посчитал бы количество цифр в начале строки, что бы определиться с форматом

регуляркой поменял бы все не цифры на точку

преобразование

и отлов ошибок, конечно.
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781087
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MirnyiAtomрегуляркой поменял бы все не цифры на точкуБыло
2019-03-01T12:08:33.654-02:00
стало
2019.03.01.12.08.33.654.02.00

Удачного парсинга
...
Рейтинг: 0 / 0
Перевести string в DateTime
    #39781117
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
zinpubValery_B,

А вот Америка пишет - MM/DD/YYYY
Значит надо сделать так, что бы в америке писали YYYY MM DD
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Перевести string в DateTime
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]