CooDi Опубликовано 16 июля, 2008 Жалоба Поделиться Опубликовано 16 июля, 2008 В общем написал такую штуку, которая должа съедать любой формат строки и выдавать дату в виде строки в формате дд.мм.гггг.Например:1. Ввод: 1-2-3Вывод: 01.02.20032.Ввод: 1Вывод: 01.07.2008(То есть считает, что забит день текущего месяца)3.Ввод: 133Вывод: 13.03.2008и т.д.Надо потестировать, найти ошибки. Если кто хочет, может оптимизировать p.s. Работает на Delphi.function textToDate(Txt:TCaption):TCaption;var day,month,year:TCaption; i,iday,imonth,iyear:integer; nd,nm,ny:word;begin iday:=0; imonth:=0; iyear:=0; for i:=1 to length(txt) do begin if txt[i] in ['1','2','3','4','5','6','7','8','9','0'] then begin if iday<2 then begin day:=day+txt[i]; inc(iday); end else if imonth<2 then begin month:=month+txt[i]; inc(imonth); end else if iyear<4 then begin year:=year+txt[i]; iyear:=iyear+1; end; end else begin if iday=1 then begin iday:=2; day:='0'+day; end; if imonth=1 then begin imonth:=2; month:='0'+month; end; if iyear=1 then begin iyear:=4; year:='200'+year; end; if iyear=2 then begin iyear:=4; if year[1]>'5' then year:='19'+year else year:='20'+year; end; if iyear=3 then begin iyear:=4; year:='1'+year; end; end; end; Decodedate(now,ny,nm,nd); case iyear of 0: begin year:=inttostr(ny); iyear:=4; end; 1: year:='200'+year; 2: if year[1]>'5' then year:='19'+year else year:='20'+year; 3: year:='1'+year; end; if iday=0 then day:=inttostr(nd); if imonth=0 then month:=inttostr(nm); iday:=strtoint(day); imonth:=strtoint(month); if length(day)<2 then day:='0'+day; if length(month)<2 then month:='0'+month; if iday=0 then day:='01'; if imonth=0 then month:='01'; if (imonth in [4,6,9,11]) and (iday>30) then day:='30'; iyear:=strtoint(year[3]+year[4]); if (imonth=2) and (iday>28) then if (iday>29) and ((iyear mod 4)=0) and (iyear<>0) then day:='29' else day:='28'; texttodate:=day+'.'+month+'.'+year;end;Добавлено спустя 1 минуту 24 секунды:Если не понятен алгоритм, спрашивайте. Вечером опишу по-подробнее. Ссылка на комментарий
toll Опубликовано 17 июля, 2008 Жалоба Поделиться Опубликовано 17 июля, 2008 112 1 декабря или 11 февраля111 вообще непонятнотак что есть для даты поле ввода ( можно как ввод по маске ) него и нада юзать Ссылка на комментарий
CooDi Опубликовано 18 июля, 2008 Автор Жалоба Поделиться Опубликовано 18 июля, 2008 если есть две цыфры подряд - он считает их как число, следующую пару - как месяц и т.д.ВВод по маске автоматически не подставляют месяц и год - поэтому не подходят. Ссылка на комментарий
bayarookie Опубликовано 18 июля, 2008 Жалоба Поделиться Опубликовано 18 июля, 2008 для ускорения ввода документов, самое оно, а юзеры тыкнутся пару раз неправильно, но потом привыкнут,просто рядом можно в Label выводить, что получается,типа в Edit1Change вызывать эту функциюLabel1.Caption := textToDate(Edit1.Text);и результат сразу будет видно Ссылка на комментарий
CooDi Опубликовано 18 июля, 2008 Автор Жалоба Поделиться Опубликовано 18 июля, 2008 bayarookieя знаю. Это я еще и написал!Так и работает. Просто я не могу ошибок найти в работе, вот и выложил, может вы ее сможете "сломать".Фишка в том, что вводить можно ЛЮБОЙ текст, она его должна пережовывать и выдавать дату.Может кто сможет код оптимизировать.ТОка не на Change а на Exit Еще алгоритм написан таким образом, чтобы легко можно было его перевести на С++ и другие языки.Добавлено спустя 3 минуты 3 секунды:Тут даже учтено исправление даты, если месяц 30 дней или 31, а также февраль в нормальный и весокосный год.Добавлено спустя 3 минуты 42 секунды:Ввводим:34хер1не5Получаем:31.01.2005 Ссылка на комментарий
bayarookie Опубликовано 18 июля, 2008 Жалоба Поделиться Опубликовано 18 июля, 2008 проверку на зашкаливаемость числа надо перенести в строку if iday<2 thenа то из 52 получается не 5 февраля, а 52 июля Ссылка на комментарий
CooDi Опубликовано 18 июля, 2008 Автор Жалоба Поделиться Опубликовано 18 июля, 2008 блин. Вообщето должен выдавать 31 июля.Добавлено спустя 1 минуту 59 секунд:хотя логичнее 5 февраля. ЩАс переделаю.Добавлено спустя 34 минуты 19 секунд:function textToDate(Txt:TCaption):TCaption;var day,month,year:TCaption; i,iday,imonth,iyear:integer; nd,nm,ny:word;begin iday:=0; imonth:=0; iyear:=0; for i:=1 to length(txt) do begin if txt[i] in ['1','2','3','4','5','6','7','8','9','0'] then begin if iday<2 then begin if (iday=2) and (strtoint(day)>=4) then begin day:='0'+day; inc(imonth); month:=txt[i]; end else day:=day+txt[i]; inc(iday); end else if imonth<2 then begin month:=month+txt[i]; //....................................... if imonth>12 then begin month:='12'; imonth:=12; end; if (imonth in [4,6,9,11]) and (iday>30) then day:='30'; if (imonth in [1,3,5,7,8,10,12]) and (iday>31) then day:='31'; iyear:=strtoint(year[3]+year[4]); if (imonth=2) and (iday>28) then if (iday>29) and ((iyear mod 4)=0) and (iyear<>0) then day:='29' else day:='28'; texttodate:=day+'.'+month+'.'+year;end;Подправленные места.Теперь логика такая - если первая цифра дня больше 4, то следующая цифра относится к месяцу (если они не разделены разделителем)Добавлено спустя 1 минуту 19 секунд:еще думаю с месяцами тоже проделать, если 523, то вводилось 05.02.2003 (щас 05.12.2008) Ссылка на комментарий
bayarookie Опубликовано 18 июля, 2008 Жалоба Поделиться Опубликовано 18 июля, 2008 так получшеа всё-таки лучше в OnChange делать, чем в OnExit, потому что, например, могут ввести что-то неправильно и сразу мышкой нажать кнопку "Сохранить" Ссылка на комментарий
Jinchuuriki Опубликовано 20 июля, 2008 Жалоба Поделиться Опубликовано 20 июля, 2008 Ыыыы.... а для чего это всё? Простите великодушно. Ссылка на комментарий
CooDi Опубликовано 20 июля, 2008 Автор Жалоба Поделиться Опубликовано 20 июля, 2008 для "тупых" пользвателей и ускорения ввода. В таком формате она сохраняется в базах данных. Ссылка на комментарий
Jinchuuriki Опубликовано 21 июля, 2008 Жалоба Поделиться Опубликовано 21 июля, 2008 А если в тексте будет подразумеваться не дата, а время 23ч. 53 мин., н-р? И если тоже будет коряво введено, н-р, 23 хбз 53 охуе.. Ссылка на комментарий
bayarookie Опубликовано 21 июля, 2008 Жалоба Поделиться Опубликовано 21 июля, 2008 обычно в базах данных нафиг не нужно время, только что-то типа, дата документа, дата проводки и тому подобная бухгалтерская хрень Ссылка на комментарий
Jinchuuriki Опубликовано 21 июля, 2008 Жалоба Поделиться Опубликовано 21 июля, 2008 Ааа... ну тогда понятно вроде... Ссылка на комментарий
CooDi Опубликовано 21 июля, 2008 Автор Жалоба Поделиться Опубликовано 21 июля, 2008 Эту функцию можно отнести к обработчикам текста после его ввода. Если обрабатывать текст одновременно с вводом, то там геморроя больше получается, т.к. приходится обрабатывать текст и последнюю нажатую клавишу (если BackSpace - то изменять ничего не надо - просто пользователь исправляет, а если цыферы, то смотреть, что вводит и исправлять, потом сравнивать месяц и день - если нужно исправлять день, а потом выяснять високосность года и опять исправлять день, если год НЕ високосный). Ссылка на комментарий
bayarookie Опубликовано 21 июля, 2008 Жалоба Поделиться Опубликовано 21 июля, 2008 нажатая клавиша - это в OnKeyPress и OnKeyDown и OnKeyUp,а в OnChange - только когда меняются данныеprocedure TForm1.Edit1Change(Sender: TObject);begin Label1.Caption := textToDate(Edit1.Text);end;вот так вот работает просто отлично Ссылка на комментарий
CooDi Опубликовано 21 июля, 2008 Автор Жалоба Поделиться Опубликовано 21 июля, 2008 Ухаха... Прикольный способ Но наверно всётаки надо выводить туда-же, потомучто "тупой" пользователь не поймет, как это - пишу тут, а пишется там. Да и к томуже не для всех языков подойдет этот способ. Ссылка на комментарий
Рекомендуемые сообщения
Пожалуйста, войдите, чтобы комментировать
Вы сможете оставить комментарий после входа в
Войти