dati.inc 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316
  1. {
  2. *********************************************************************
  3. Copyright (C) 1997, 1998 Gertjan Schouten
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. *********************************************************************
  16. System Utilities For Free Pascal
  17. }
  18. {==============================================================================}
  19. { internal functions }
  20. {==============================================================================}
  21. Function DoEncodeDate(Year, Month, Day: Word): longint;
  22. Var
  23. D : TDateTime;
  24. begin
  25. If TryEncodeDate(Year,Month,Day,D) then
  26. Result:=Trunc(D)
  27. else
  28. Result:=0;
  29. end;
  30. function DoEncodeTime(Hour, Minute, Second, MilliSecond: word): TDateTime;
  31. begin
  32. If not TryEncodeTime(Hour,Minute,Second,MilliSecond,Result) then
  33. Result:=0;
  34. end;
  35. {==============================================================================}
  36. { Public functions }
  37. {==============================================================================}
  38. { ComposeDateTime converts a Date and a Time into one TDateTime }
  39. function ComposeDateTime(Date,Time : TDateTime) : TDateTime;
  40. begin
  41. if Date < 0 then Result := trunc(Date) - Abs(frac(Time))
  42. else Result := trunc(Date) + Abs(frac(Time));
  43. end;
  44. { DateTimeToTimeStamp converts DateTime to a TTimeStamp }
  45. function DateTimeToTimeStamp(DateTime: TDateTime): TTimeStamp;
  46. begin
  47. result.Time := Round(abs(Frac(DateTime)) * MSecsPerDay);
  48. result.Date := DateDelta + trunc(DateTime);
  49. end ;
  50. { TimeStampToDateTime converts TimeStamp to a TDateTime value }
  51. function TimeStampToDateTime(const TimeStamp: TTimeStamp): TDateTime;
  52. begin
  53. Result := ComposeDateTime(TimeStamp.Date - DateDelta,TimeStamp.Time / MSecsPerDay)
  54. end;
  55. { MSecsToTimeStamp }
  56. function MSecsToTimeStamp(MSecs: comp): TTimeStamp;
  57. begin
  58. result.Date := Trunc(msecs / msecsperday);
  59. msecs:= msecs-comp(result.date)*msecsperday;
  60. result.Time := Round(MSecs);
  61. end ;
  62. { TimeStampToMSecs }
  63. function TimeStampToMSecs(const TimeStamp: TTimeStamp): comp;
  64. begin
  65. result := TimeStamp.Time + comp(timestamp.date)*msecsperday;
  66. end ;
  67. Function TryEncodeDate(Year,Month,Day : Word; Out Date : TDateTime) : Boolean;
  68. var
  69. c, ya: cardinal;
  70. begin
  71. Result:=(Year>0) and (Year<10000) and
  72. (Month in [1..12]) and
  73. (Day>0) and (Day<=MonthDays[IsleapYear(Year),Month]);
  74. If Result then
  75. begin
  76. if month > 2 then
  77. Dec(Month,3)
  78. else
  79. begin
  80. Inc(Month,9);
  81. Dec(Year);
  82. end;
  83. c:= Year DIV 100;
  84. ya:= Year - 100*c;
  85. Date := (146097*c) SHR 2 + (1461*ya) SHR 2 + (153*cardinal(Month)+2) DIV 5 + cardinal(Day);
  86. // Note that this line can't be part of the line above, since TDateTime is
  87. // signed and c and ya are not
  88. Date := Date - 693900;
  89. end
  90. end;
  91. function TryEncodeTime(Hour, Min, Sec, MSec:word; Out Time : TDateTime) : boolean;
  92. begin
  93. Result:=(Hour<24) and (Min<60) and (Sec<60) and (MSec<1000);
  94. If Result then
  95. Time:=TDateTime(cardinal(Hour)*3600000+cardinal(Min)*60000+cardinal(Sec)*1000+MSec)/MSecsPerDay;
  96. end;
  97. { EncodeDate packs three variables Year, Month and Day into a
  98. TDateTime value the result is the number of days since 12/30/1899 }
  99. function EncodeDate(Year, Month, Day: word): TDateTime;
  100. begin
  101. If Not TryEncodeDate(Year,Month,Day,Result) then
  102. Raise EConvertError.CreateFmt('%d-%d-%d is not a valid date specification',
  103. [Year,Month,Day]);
  104. end;
  105. { EncodeTime packs four variables Hour, Minute, Second and MilliSecond into
  106. a TDateTime value }
  107. function EncodeTime(Hour, Minute, Second, MilliSecond:word):TDateTime;
  108. begin
  109. If not TryEncodeTime(Hour,Minute,Second,MilliSecond,Result) then
  110. Raise EConvertError.CreateFmt('%d:%d:%d.%d is not a valid time specification',
  111. [Hour,Minute,Second,MilliSecond]);
  112. end;
  113. { DecodeDate unpacks the value Date into three values:
  114. Year, Month and Day }
  115. procedure DecodeDate(Date: TDateTime; out Year, Month, Day: word);
  116. var
  117. ly,ld,lm,j : cardinal;
  118. begin
  119. if Date <= -datedelta then // If Date is before 1-1-1 then return 0-0-0
  120. begin
  121. Year := 0;
  122. Month := 0;
  123. Day := 0;
  124. end
  125. else
  126. begin
  127. j := pred((Trunc(System.Int(Date)) + 693900) SHL 2);
  128. ly:= j DIV 146097;
  129. j:= j - 146097 * cardinal(ly);
  130. ld := j SHR 2;
  131. j:=(ld SHL 2 + 3) DIV 1461;
  132. ld:= (cardinal(ld) SHL 2 + 7 - 1461*j) SHR 2;
  133. lm:=(5 * ld-3) DIV 153;
  134. ld:= (5 * ld +2 - 153*lm) DIV 5;
  135. ly:= 100 * cardinal(ly) + j;
  136. if lm < 10 then
  137. inc(lm,3)
  138. else
  139. begin
  140. dec(lm,9);
  141. inc(ly);
  142. end;
  143. year:=ly;
  144. month:=lm;
  145. day:=ld;
  146. end;
  147. end;
  148. function DecodeDateFully(const DateTime: TDateTime; out Year, Month, Day, DOW: Word): Boolean;
  149. begin
  150. DecodeDate(DateTime,Year,Month,Day);
  151. DOW:=DayOfWeek(DateTime);
  152. Result:=IsLeapYear(Year);
  153. end;
  154. { DecodeTime unpacks Time into four values:
  155. Hour, Minute, Second and MilliSecond }
  156. procedure DecodeTime(Time: TDateTime; out Hour, Minute, Second, MilliSecond: word);
  157. Var
  158. l : cardinal;
  159. begin
  160. l := Round(abs(Frac(time)) * MSecsPerDay);
  161. Hour := l div 3600000;
  162. l := l mod 3600000;
  163. Minute := l div 60000;
  164. l := l mod 60000;
  165. Second := l div 1000;
  166. l := l mod 1000;
  167. MilliSecond := l;
  168. end;
  169. { DateTimeToSystemTime converts DateTime value to SystemTime }
  170. procedure DateTimeToSystemTime(DateTime: TDateTime; out SystemTime: TSystemTime);
  171. begin
  172. DecodeDate(DateTime, SystemTime.Year, SystemTime.Month, SystemTime.Day);
  173. DecodeTime(DateTime, SystemTime.Hour, SystemTime.Minute, SystemTime.Second, SystemTime.MilliSecond);
  174. end ;
  175. { SystemTimeToDateTime converts SystemTime to a TDateTime value }
  176. function SystemTimeToDateTime(const SystemTime: TSystemTime): TDateTime;
  177. begin
  178. result := ComposeDateTime(DoEncodeDate(SystemTime.Year, SystemTime.Month, SystemTime.Day),
  179. DoEncodeTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second, SystemTime.MilliSecond));
  180. end ;
  181. { DayOfWeek returns the Day of the week (sunday is day 1) }
  182. function DayOfWeek(DateTime: TDateTime): integer;
  183. begin
  184. Result := 1 + (Abs(Trunc(DateTime) - 1) mod 7);
  185. end ;
  186. { Date returns the current Date }
  187. function Date: TDateTime;
  188. var
  189. SystemTime: TSystemTime;
  190. begin
  191. GetLocalTime(SystemTime);
  192. result := DoEncodeDate(SystemTime.Year, SystemTime.Month, SystemTime.Day);
  193. end ;
  194. { Time returns the current Time }
  195. function Time: TDateTime;
  196. var
  197. SystemTime: TSystemTime;
  198. begin
  199. GetLocalTime(SystemTime);
  200. Result := DoEncodeTime(SystemTime.Hour,SystemTime.Minute,SystemTime.Second,SystemTime.MilliSecond);
  201. end ;
  202. { Now returns the current Date and Time }
  203. function Now: TDateTime;
  204. var
  205. SystemTime: TSystemTime;
  206. begin
  207. GetLocalTime(SystemTime);
  208. result := systemTimeToDateTime(SystemTime);
  209. end;
  210. { IncMonth increments DateTime with NumberOfMonths months,
  211. NumberOfMonths can be less than zero }
  212. function IncMonth(const DateTime: TDateTime; NumberOfMonths: integer = 1 ): TDateTime;
  213. var
  214. Year, Month, Day : word;
  215. begin
  216. DecodeDate(DateTime, Year, Month, Day);
  217. IncAMonth(Year, Month, Day, NumberOfMonths);
  218. result := ComposeDateTime(DoEncodeDate(Year, Month, Day), DateTime);
  219. end ;
  220. { IncAMonth is the same as IncMonth, but operates on decoded date }
  221. procedure IncAMonth(var Year, Month, Day: Word; NumberOfMonths: Integer = 1);
  222. var
  223. TempMonth, S: Integer;
  224. begin
  225. If NumberOfMonths>=0 then
  226. s:=1
  227. else
  228. s:=-1;
  229. inc(Year,(NumberOfMonths div 12));
  230. TempMonth:=Month+(NumberOfMonths mod 12)-1;
  231. if (TempMonth>11) or
  232. (TempMonth<0) then
  233. begin
  234. Dec(TempMonth, S*12);
  235. Inc(Year, S);
  236. end;
  237. Month:=TempMonth+1; { Months from 1 to 12 }
  238. If (Day>MonthDays[IsLeapYear(Year)][Month]) then
  239. Day:=MonthDays[IsLeapYear(Year)][Month];
  240. end;
  241. { IsLeapYear returns true if Year is a leap year }
  242. function IsLeapYear(Year: Word): boolean;
  243. begin
  244. Result := (Year mod 4 = 0) and ((Year mod 100 <> 0) or (Year mod 400 = 0));
  245. end;
  246. { DateToStr returns a string representation of Date using ShortDateFormat }
  247. function DateToStr(Date: TDateTime): string;
  248. begin
  249. DateTimeToString(Result, 'ddddd', Date);
  250. end ;
  251. function DateToStr(Date: TDateTime; const FormatSettings: TFormatSettings): string;
  252. begin
  253. DateTimeToString(result, FormatSettings.ShortDateFormat, Date, FormatSettings);
  254. end;
  255. { TimeToStr returns a string representation of Time using LongTimeFormat }
  256. function TimeToStr(Time: TDateTime): string;
  257. begin
  258. DateTimeToString(Result, 'tt', Time);
  259. end ;
  260. function TimeToStr(Time: TDateTime; const FormatSettings: TFormatSettings): string;
  261. begin
  262. DateTimeToString(Result, FormatSettings.LongTimeFormat, Time, FormatSettings);
  263. end;
  264. { DateTimeToStr returns a string representation of DateTime using LongDateTimeFormat }
  265. function DateTimeToStr(DateTime: TDateTime): string;
  266. begin
  267. DateTimeToString(Result, 'c', DateTime);
  268. end ;
  269. function DateTimeToStr(DateTime: TDateTime; const FormatSettings: TFormatSettings): string;
  270. begin
  271. DateTimeToString(Result, 'c', DateTime ,FormatSettings);
  272. end;
  273. { StrToDate converts the string S to a TDateTime value
  274. if S does not represent a valid date value
  275. an EConvertError will be raised }
  276. function IntStrToDate(Out ErrorMsg : AnsiString; const S: PChar; Len : integer; const useformat : string; const defs:TFormatSettings; separator : char = #0): TDateTime;
  277. const SInvalidDateFormat = '"%s" is not a valid date format';
  278. procedure FixErrorMsg(const errm :ansistring;const errmarg : ansistring);
  279. begin
  280. errormsg:=format(errm,[errmarg]);
  281. end;
  282. var
  283. df:string;
  284. d,m,y,ly:word;
  285. n,i:longint;
  286. c:word;
  287. dp,mp,yp,which : Byte;
  288. s1:string[4];
  289. values:array[1..3] of longint;
  290. LocalTime:tsystemtime;
  291. YearMoreThenTwoDigits : boolean;
  292. begin
  293. ErrorMsg:=''; Result:=0;
  294. if (Len=0) then
  295. begin
  296. FixErrorMsg(SInvalidDateFormat,'');
  297. exit;
  298. end;
  299. YearMoreThenTwoDigits := False;
  300. if separator = #0 then
  301. separator := defs.DateSeparator;
  302. df := UpperCase(useFormat);
  303. { Determine order of D,M,Y }
  304. yp:=0;
  305. mp:=0;
  306. dp:=0;
  307. Which:=0;
  308. i:=0;
  309. while (i<Length(df)) and (Which<3) do
  310. begin
  311. inc(i);
  312. Case df[i] of
  313. 'Y' :
  314. if yp=0 then
  315. begin
  316. Inc(Which);
  317. yp:=which;
  318. end;
  319. 'M' :
  320. if mp=0 then
  321. begin
  322. Inc(Which);
  323. mp:=which;
  324. end;
  325. 'D' :
  326. if dp=0 then
  327. begin
  328. Inc(Which);
  329. dp:=which;
  330. end;
  331. end;
  332. end;
  333. if Which<>3 then
  334. begin
  335. FixErrorMsg(SErrIllegalDateFormatString,useformat);
  336. Exit;
  337. end;
  338. { Get actual values }
  339. for i := 1 to 3 do
  340. values[i] := 0;
  341. s1 := '';
  342. n := 0;
  343. dec(len);
  344. for i := 0 to len do
  345. begin
  346. if s[i] in ['0'..'9'] then
  347. s1 := s1 + s[i];
  348. { space can be part of the shortdateformat, and is defaultly in slovak
  349. windows, therefor it shouldn't be taken as separator (unless so specified)
  350. and ignored }
  351. if (Separator <> ' ') and (s[i] = ' ') then
  352. Continue;
  353. if (s[i] = separator) or ((i = len) and (s[i] in ['0'..'9'])) then
  354. begin
  355. inc(n);
  356. if n>3 then
  357. begin
  358. FixErrorMsg(SInvalidDateFormat,s);
  359. exit;
  360. end;
  361. // Check if the year has more then two digits (if n=yp, then we are evaluating the year.)
  362. if (n=yp) and (length(s1)>2) then YearMoreThenTwoDigits := True;
  363. val(s1, values[n], c);
  364. if c<>0 then
  365. begin
  366. FixErrorMsg(SInvalidDateFormat,s);
  367. Exit;
  368. end;
  369. s1 := '';
  370. end
  371. else if not (s[i] in ['0'..'9']) then
  372. begin
  373. FixErrorMsg(SInvalidDateFormat,s);
  374. Exit;
  375. end;
  376. end ;
  377. // Fill in values.
  378. getLocalTime(LocalTime);
  379. ly := LocalTime.Year;
  380. If N=3 then
  381. begin
  382. y:=values[yp];
  383. m:=values[mp];
  384. d:=values[dp];
  385. end
  386. Else
  387. begin
  388. Y:=ly;
  389. If n<2 then
  390. begin
  391. d:=values[1];
  392. m := LocalTime.Month;
  393. end
  394. else
  395. If dp<mp then
  396. begin
  397. d:=values[1];
  398. m:=values[2];
  399. end
  400. else
  401. begin
  402. d:=values[2];
  403. m:=values[1];
  404. end;
  405. end;
  406. if (y >= 0) and (y < 100) and not YearMoreThenTwoDigits then
  407. begin
  408. ly := ly - defs.TwoDigitYearCenturyWindow;
  409. Inc(Y, ly div 100 * 100);
  410. if (defs.TwoDigitYearCenturyWindow > 0) and (Y < ly) then
  411. Inc(Y, 100);
  412. end;
  413. if not TryEncodeDate(y, m, d, result) then
  414. errormsg:='Invalid date';
  415. end;
  416. function StrToDate(const S: PChar; Len : integer; const useformat : string; separator : char = #0): TDateTime;
  417. Var
  418. MSg : AnsiString;
  419. begin
  420. Result:=IntStrToDate(Msg,S,Len,useFormat,DefaultFormatSettings,Separator);
  421. If (Msg<>'') then
  422. Raise EConvertError.Create(Msg);
  423. end;
  424. function StrToDate(const S: ShortString; const useformat : string; separator : char = #0): TDateTime;
  425. begin
  426. result := StrToDate(@S[1],Length(s),UseFormat,separator);
  427. end;
  428. function StrToDate(const S: AnsiString; const useformat : string; separator : char = #0): TDateTime;
  429. begin
  430. result := StrToDate(@S[1],Length(s),UseFormat,separator);
  431. end;
  432. function StrToDate(const S: ShortString; separator : char): TDateTime;
  433. begin
  434. result := StrToDate(@S[1],Length(s),ShortDateFormat,separator)
  435. end;
  436. function StrToDate(const S: ShortString): TDateTime;
  437. begin
  438. result := StrToDate(@S[1],Length(s),ShortDateFormat,#0);
  439. end;
  440. function StrToDate(const S: AnsiString; separator : char): TDateTime;
  441. begin
  442. result := StrToDate(@S[1],Length(s),ShortDateFormat,separator)
  443. end;
  444. function StrToDate(const S: AnsiString): TDateTime;
  445. begin
  446. result := StrToDate(@S[1],Length(s),ShortDateFormat,#0);
  447. end;
  448. { StrToTime converts the string S to a TDateTime value
  449. if S does not represent a valid time value an
  450. EConvertError will be raised }
  451. function IntStrToTime(Out ErrorMsg : AnsiString; const S: PChar; Len : integer;const defs:TFormatSettings; separator : char = #0): TDateTime;
  452. const
  453. AMPM_None = 0;
  454. AMPM_AM = 1;
  455. AMPM_PM = 2;
  456. tiHour = 0;
  457. tiMin = 1;
  458. tiSec = 2;
  459. tiMSec = 3;
  460. type
  461. TTimeValues = array[tiHour..tiMSec] of Word;
  462. var
  463. AmPm: integer;
  464. TimeValues: TTimeValues;
  465. function StrPas(Src : PChar; len: integer = 0) : ShortString;
  466. begin
  467. //this is unsafe for len > 255, it will trash memory (I tested this)
  468. //reducing it is safe, since whenever we use this a string > 255 is invalid anyway
  469. if len > 255 then len := 255;
  470. SetLength(Result, len);
  471. move(src[0],result[1],len);
  472. end;
  473. function SplitElements(out TimeValues: TTimeValues; out AmPm: Integer): Boolean;
  474. //Strict version. It does not allow #32 as Separator, it will treat it as whitespace always
  475. const
  476. Digits = ['0'..'9'];
  477. var
  478. Cur, Offset, ElemLen, Err, TimeIndex, FirstSignificantDigit: Integer;
  479. Value: Word;
  480. DigitPending, MSecPending: Boolean;
  481. AmPmStr: ShortString;
  482. CurChar: Char;
  483. begin
  484. Result := False;
  485. AmPm := AMPM_None; //No Am or PM in string found yet
  486. MSecPending := False;
  487. TimeIndex := 0; //indicating which TTimeValue must be filled next
  488. FillChar(TimeValues, SizeOf(TTimeValues), 0);
  489. Cur := 0;
  490. //skip leading blanks
  491. While (Cur < Len) and (S[Cur] =#32) do Inc(Cur);
  492. Offset := Cur;
  493. //First non-blank cannot be Separator or DecimalSeparator
  494. if (Cur > Len - 1) or (S[Cur] = Separator) or (S[Cur] = defs.Decimalseparator) then Exit;
  495. DigitPending := (S[Cur] in Digits);
  496. While (Cur < Len) do
  497. begin
  498. //writeln;
  499. //writeln('Main While loop: Cur = ',Cur,' S[Cur] = "',S[Cur],'" Len = ',Len);
  500. CurChar := S[Cur];
  501. if CurChar in Digits then
  502. begin//Digits
  503. //HH, MM, SS, or Msec?
  504. //writeln('Digit');
  505. //Digits are only allowed after starting Am/PM or at beginning of string or after Separator
  506. //and TimeIndex must be <= tiMSec
  507. //Uncomment "or (#32 = Separator)" and it will allllow #32 as separator
  508. if (not (DigitPending {or (#32 = Separator)})) or (TimeIndex > tiMSec) then Exit;
  509. OffSet := Cur;
  510. if (CurChar <> '0') then FirstSignificantDigit := OffSet else FirstSignificantDigit := -1;
  511. while (Cur < Len -1) and (S[Cur + 1] in Digits) do
  512. begin
  513. //Mark first Digit that is not '0'
  514. if (FirstSignificantDigit = -1) and (S[Cur] <> '0') then FirstSignificantDigit := Cur;
  515. Inc(Cur);
  516. end;
  517. if (FirstSignificantDigit = -1) then FirstSignificantDigit := Cur;
  518. ElemLen := 1 + Cur - FirstSignificantDigit;
  519. //writeln(' S[FirstSignificantDigit] = ',S[FirstSignificantDigit], ' S[Cur] = ',S[Cur],' ElemLen = ',ElemLen,' -> ', StrPas(S + Offset, ElemLen));
  520. //writeln(' Cur = ',Cur);
  521. //this way we know that Val() will never overflow Value !
  522. if (ElemLen <= 2) or ((ElemLen <= 3) and (TimeIndex = tiMSec) ) then
  523. begin
  524. Val(StrPas(S + FirstSignificantDigit, ElemLen), Value, Err);
  525. //writeln(' Value = ',Value,' HH = ',TimeValues[0],' MM = ',TimeValues[1],' SS = ',TimeValues[2],' MSec = ',Timevalues[3]);
  526. //This is safe now, because we know Value < High(Word)
  527. TimeValues[TimeIndex] := Value;
  528. Inc(TimeIndex);
  529. DigitPending := False;
  530. end
  531. else Exit; //Value to big, so it must be a wrong timestring
  532. end//Digits
  533. else if (CurChar = #32) then
  534. begin
  535. //writeln('#32');
  536. //just skip, but we must adress this, or it will be parsed by either AM/PM or Separator
  537. end
  538. else if (CurChar = Separator) then
  539. begin
  540. //writeln('Separator');
  541. if DigitPending or (TimeIndex > tiSec) then Exit;
  542. DigitPending := True;
  543. MSecPending := False;
  544. end
  545. else if (CurChar = defs.DecimalSeparator) then
  546. begin
  547. //writeln('DecimalSeparator');
  548. if DigitPending or MSecPending or (TimeIndex <> tiMSec) then Exit;
  549. DigitPending := True;
  550. MSecPending := True;
  551. end
  552. else
  553. begin//AM/PM?
  554. //None of the above, so this char _must_ be the start of AM/PM string
  555. //If we already have found AM/PM or we expect a digit then then timestring must be wrong at this point
  556. //writeln('AM/PM?');
  557. if (AmPm <> AMPM_None) or DigitPending then Exit;
  558. OffSet := Cur;
  559. while (Cur < Len -1) and (not (S[Cur + 1] in [Separator, #32, defs.DecimalSeparator]))
  560. and not (S[Cur + 1] in Digits) do Inc(Cur);
  561. ElemLen := 1 + Cur - OffSet;
  562. //writeln(' S[Offset] = ',S[Offset], ' S[Cur] = ',S[Cur],' ElemLen = ',ElemLen,' -> ', StrPas(S + Offset, ElemLen));
  563. //writeln(' Cur = ',Cur);
  564. AmPmStr := StrPas(S + OffSet, ElemLen);
  565. //writeln('AmPmStr = ',ampmstr,' (',length(ampmstr),')');
  566. //We must compare to TimeAMString before hardcoded 'AM' for delphi compatibility
  567. //Also it is perfectly legal, though insane to have TimeAMString = 'PM' and vice versa
  568. if (AnsiCompareText(AmPmStr, defs.TimeAMString) = 0) then AmPm := AMPM_AM
  569. else if (AnsiCompareText(AmPmStr, defs.TimePMString) = 0) then AmPm := AMPM_PM
  570. else if (CompareText(AmPmStr, 'AM') = 0) then AmPm := AMPM_AM
  571. else if (CompareText(AmPmStr, 'PM') = 0) then AmPm := AMPM_PM
  572. else Exit; //If text does not match any of these, timestring must be wrong;
  573. //if AM/PM is at beginning of string, then a digit is mandatory after it
  574. if (TimeIndex = tiHour) then
  575. begin
  576. DigitPending := True;
  577. end
  578. //otherwise, no more TimeValues allowed after this
  579. else
  580. begin
  581. TimeIndex := tiMSec + 1;
  582. DigitPending := False;
  583. end;
  584. end;//AM/PM
  585. Inc(Cur)
  586. end;//while
  587. //If we arrive here, parsing the elements has been successfull
  588. //if not at least Hours specified then input is not valid
  589. //when am/pm is specified Hour must be <= 12 and not 0
  590. if (TimeIndex = tiHour) or ((AmPm <> AMPM_None) and ((TimeValues[tiHour] > 12) or (TimeValues[tiHour] = 0))) or DigitPending then Exit;
  591. Result := True;
  592. end;
  593. begin
  594. if separator = #0 then
  595. separator := defs.TimeSeparator;
  596. AmPm := AMPM_None;
  597. if not SplitElements(TimeValues, AmPm) then
  598. begin
  599. ErrorMsg:=Format(SErrInvalidTimeFormat,[StrPas(S, Len)]);
  600. Exit;
  601. end;
  602. if (AmPm=AMPM_PM) and (TimeValues[tiHour]<>12) then Inc(TimeValues[tiHour], 12)
  603. else if (AmPm=AMPM_AM) and (TimeValues[tiHour]=12) then TimeValues[tiHour]:=0;
  604. if not TryEncodeTime(TimeValues[tiHour], TimeValues[tiMin], TimeValues[tiSec], TimeValues[tiMSec], result) Then
  605. //errormsg:='Invalid time.';
  606. ErrorMsg:=Format(SErrInvalidTimeFormat,[StrPas(S, Len)]);
  607. end ;
  608. function StrToTime(const S: PChar; Len : integer; separator : char = #0): TDateTime;
  609. Var
  610. Msg : AnsiString;
  611. begin
  612. Result:=IntStrToTime(Msg,S,Len,DefaultFormatSettings,Separator);
  613. If (Msg<>'') then
  614. Raise EConvertError.Create(Msg);
  615. end;
  616. function StrToTime(const s: ShortString; separator : char): TDateTime;
  617. begin
  618. result := StrToTime(@s[1], length(s), separator);
  619. end;
  620. function StrToTime(const s: AnsiString; separator : char): TDateTime;
  621. begin
  622. result := StrToTime(@s[1], length(s), separator);
  623. end;
  624. function StrToTime(const s: ShortString): TDateTime;
  625. begin
  626. result := StrToTime(@s[1], length(s), #0);
  627. end;
  628. function StrToTime(const s: AnsiString): TDateTime;
  629. begin
  630. result := StrToTime(@s[1], length(s), #0);
  631. end;
  632. { StrToDateTime converts the string S to a TDateTime value
  633. if S does not represent a valid date and/or time value
  634. an EConvertError will be raised }
  635. function StrToDateTime(const s: string): TDateTime;
  636. var
  637. I: integer;
  638. begin
  639. I:=Pos(TimeSeparator,S);
  640. If (I>0) then
  641. begin
  642. While (I>0) and (S[I]<>' ') do
  643. Dec(I);
  644. If I>0 then
  645. result:=ComposeDateTime(StrToDate(Copy(S,1,I-1)),StrToTime(Copy(S,i+1, Length(S)-i)))
  646. else
  647. result:=StrToTime(S)
  648. end
  649. else
  650. Result:=StrToDate(S);
  651. end;
  652. function StrToDateTime(const s: AnsiString; const UseFormat : TFormatSettings): TDateTime;
  653. var
  654. I: integer;
  655. begin
  656. I:=Pos(TimeSeparator,S);
  657. If (I>0) then
  658. begin
  659. While (I>0) and (S[I]<>' ') do
  660. Dec(I);
  661. If I>0 then
  662. result:=ComposeDateTime(StrToDate(Copy(S,1,I-1),UseFormat.ShortDateFormat,UseFormat.DateSeparator),
  663. StrToTime(Copy(S,i+1, Length(S)-i),UseFormat.TimeSeparator))
  664. else
  665. result:=StrToTime(S,UseFormat.TimeSeparator)
  666. end
  667. else
  668. Result:=StrToDate(S,UseFormat.ShortDateFormat,UseFormat.DateSeparator);
  669. end;
  670. function StrToDateTime(const s: ShortString; const UseFormat : TFormatSettings): TDateTime;
  671. var
  672. I: integer;
  673. begin
  674. I:=Pos(TimeSeparator,S);
  675. If (I>0) then
  676. begin
  677. While (I>0) and (S[I]<>' ') do
  678. Dec(I);
  679. If I>0 then
  680. result:=ComposeDateTime(StrToDate(Copy(S,1,I-1),UseFormat.ShortDateFormat,UseFormat.DateSeparator),
  681. StrToTime(Copy(S,i+1, Length(S)-i),UseFormat.TimeSeparator))
  682. else
  683. result:=StrToTime(S,UseFormat.TimeSeparator)
  684. end
  685. else
  686. Result:=StrToDate(S,UseFormat.ShortDateFormat,UseFormat.DateSeparator);
  687. end;
  688. { FormatDateTime formats DateTime to the given format string FormatStr }
  689. function FormatDateTime(const FormatStr: string; DateTime: TDateTime): string;
  690. begin
  691. DateTimeToString(Result, FormatStr, DateTime, DefaultFormatSettings);
  692. end;
  693. function FormatDateTime(const FormatStr: string; DateTime: TDateTime; const FormatSettings: TFormatSettings): string;
  694. begin
  695. DateTimeToString(Result, FormatStr, DateTime, FormatSettings);
  696. end;
  697. { DateTimeToString formats DateTime to the given format in FormatStr }
  698. procedure DateTimeToString(out Result: string; const FormatStr: string; const DateTime: TDateTime);
  699. begin
  700. DateTimeToString(Result, FormatStr, DateTime, DefaultFormatSettings);
  701. end;
  702. procedure DateTimeToString(out Result: string; const FormatStr: string; const DateTime: TDateTime; const FormatSettings: TFormatSettings);
  703. var
  704. ResultLen: integer;
  705. ResultBuffer: array[0..255] of char;
  706. ResultCurrent: pchar;
  707. procedure StoreStr(Str: PChar; Len: Integer);
  708. begin
  709. if ResultLen + Len < SizeOf(ResultBuffer) then
  710. begin
  711. StrMove(ResultCurrent, Str, Len);
  712. ResultCurrent := ResultCurrent + Len;
  713. ResultLen := ResultLen + Len;
  714. end;
  715. end;
  716. procedure StoreString(const Str: string);
  717. var Len: integer;
  718. begin
  719. Len := Length(Str);
  720. if ResultLen + Len < SizeOf(ResultBuffer) then
  721. begin
  722. StrMove(ResultCurrent, pchar(Str), Len);
  723. ResultCurrent := ResultCurrent + Len;
  724. ResultLen := ResultLen + Len;
  725. end;
  726. end;
  727. procedure StoreInt(Value, Digits: Integer);
  728. var
  729. S: string[16];
  730. Len: integer;
  731. begin
  732. System.Str(Value:Digits, S);
  733. for Len := 1 to Length(S) do
  734. begin
  735. if S[Len] = ' ' then
  736. S[Len] := '0'
  737. else
  738. Break;
  739. end;
  740. StoreStr(pchar(@S[1]), Length(S));
  741. end ;
  742. var
  743. Year, Month, Day, DayOfWeek, Hour, Minute, Second, MilliSecond: word;
  744. procedure StoreFormat(const FormatStr: string; Nesting: Integer; TimeFlag: Boolean);
  745. var
  746. Token, lastformattoken: char;
  747. FormatCurrent: pchar;
  748. FormatEnd: pchar;
  749. Count: integer;
  750. Clock12: boolean;
  751. P: pchar;
  752. tmp: integer;
  753. begin
  754. if Nesting > 1 then // 0 is original string, 1 is included FormatString
  755. Exit;
  756. FormatCurrent := PChar(FormatStr);
  757. FormatEnd := FormatCurrent + Length(FormatStr);
  758. Clock12 := false;
  759. P := FormatCurrent;
  760. // look for unquoted 12-hour clock token
  761. while P < FormatEnd do
  762. begin
  763. Token := P^;
  764. case Token of
  765. '''', '"':
  766. begin
  767. Inc(P);
  768. while (P < FormatEnd) and (P^ <> Token) do
  769. Inc(P);
  770. end;
  771. 'A', 'a':
  772. begin
  773. if (StrLIComp(P, 'A/P', 3) = 0) or
  774. (StrLIComp(P, 'AMPM', 4) = 0) or
  775. (StrLIComp(P, 'AM/PM', 5) = 0) then
  776. begin
  777. Clock12 := true;
  778. break;
  779. end;
  780. end;
  781. end; // case
  782. Inc(P);
  783. end ;
  784. token := #255;
  785. lastformattoken := ' ';
  786. while FormatCurrent < FormatEnd do
  787. begin
  788. Token := UpCase(FormatCurrent^);
  789. Count := 1;
  790. P := FormatCurrent + 1;
  791. case Token of
  792. '''', '"':
  793. begin
  794. while (P < FormatEnd) and (p^ <> Token) do
  795. Inc(P);
  796. Inc(P);
  797. Count := P - FormatCurrent;
  798. StoreStr(FormatCurrent + 1, Count - 2);
  799. end ;
  800. 'A':
  801. begin
  802. if StrLIComp(FormatCurrent, 'AMPM', 4) = 0 then
  803. begin
  804. Count := 4;
  805. if Hour < 12 then
  806. StoreString(FormatSettings.TimeAMString)
  807. else
  808. StoreString(FormatSettings.TimePMString);
  809. end
  810. else if StrLIComp(FormatCurrent, 'AM/PM', 5) = 0 then
  811. begin
  812. Count := 5;
  813. if Hour < 12 then StoreStr(FormatCurrent, 2)
  814. else StoreStr(FormatCurrent+3, 2);
  815. end
  816. else if StrLIComp(FormatCurrent, 'A/P', 3) = 0 then
  817. begin
  818. Count := 3;
  819. if Hour < 12 then StoreStr(FormatCurrent, 1)
  820. else StoreStr(FormatCurrent+2, 1);
  821. end
  822. else
  823. raise EConvertError.Create('Illegal character in format string');
  824. end ;
  825. '/': StoreStr(@FormatSettings.DateSeparator, 1);
  826. ':': StoreStr(@FormatSettings.TimeSeparator, 1);
  827. ' ', 'C', 'D', 'H', 'M', 'N', 'S', 'T', 'Y','Z' :
  828. begin
  829. while (P < FormatEnd) and (UpCase(P^) = Token) do
  830. Inc(P);
  831. Count := P - FormatCurrent;
  832. case Token of
  833. ' ': StoreStr(FormatCurrent, Count);
  834. 'Y': begin
  835. if Count > 2 then
  836. StoreInt(Year, 4)
  837. else
  838. StoreInt(Year mod 100, 2);
  839. end;
  840. 'M': begin
  841. if (lastformattoken = 'H') or TimeFlag then
  842. begin
  843. if Count = 1 then
  844. StoreInt(Minute, 0)
  845. else
  846. StoreInt(Minute, 2);
  847. end
  848. else
  849. begin
  850. case Count of
  851. 1: StoreInt(Month, 0);
  852. 2: StoreInt(Month, 2);
  853. 3: StoreString(FormatSettings.ShortMonthNames[Month]);
  854. else
  855. StoreString(FormatSettings.LongMonthNames[Month]);
  856. end;
  857. end;
  858. end;
  859. 'D': begin
  860. case Count of
  861. 1: StoreInt(Day, 0);
  862. 2: StoreInt(Day, 2);
  863. 3: StoreString(FormatSettings.ShortDayNames[DayOfWeek]);
  864. 4: StoreString(FormatSettings.LongDayNames[DayOfWeek]);
  865. 5: StoreFormat(FormatSettings.ShortDateFormat, Nesting+1, False);
  866. else
  867. StoreFormat(FormatSettings.LongDateFormat, Nesting+1, False);
  868. end ;
  869. end ;
  870. 'H': if Clock12 then
  871. begin
  872. tmp := hour mod 12;
  873. if tmp=0 then tmp:=12;
  874. if Count = 1 then
  875. StoreInt(tmp, 0)
  876. else
  877. StoreInt(tmp, 2);
  878. end
  879. else begin
  880. if Count = 1 then
  881. StoreInt(Hour, 0)
  882. else
  883. StoreInt(Hour, 2);
  884. end;
  885. 'N': if Count = 1 then
  886. StoreInt(Minute, 0)
  887. else
  888. StoreInt(Minute, 2);
  889. 'S': if Count = 1 then
  890. StoreInt(Second, 0)
  891. else
  892. StoreInt(Second, 2);
  893. 'Z': if Count = 1 then
  894. StoreInt(MilliSecond, 0)
  895. else
  896. StoreInt(MilliSecond, 3);
  897. 'T': if Count = 1 then
  898. StoreFormat(FormatSettings.ShortTimeFormat, Nesting+1, True)
  899. else
  900. StoreFormat(FormatSettings.LongTimeFormat, Nesting+1, True);
  901. 'C': begin
  902. StoreFormat(FormatSettings.ShortDateFormat, Nesting+1, False);
  903. if (Hour<>0) or (Minute<>0) or (Second<>0) then
  904. begin
  905. StoreString(' ');
  906. StoreFormat(FormatSettings.LongTimeFormat, Nesting+1, True);
  907. end;
  908. end;
  909. end;
  910. lastformattoken := token;
  911. end;
  912. else
  913. StoreStr(@Token, 1);
  914. end ;
  915. Inc(FormatCurrent, Count);
  916. end;
  917. end;
  918. begin
  919. DecodeDateFully(DateTime, Year, Month, Day, DayOfWeek);
  920. DecodeTime(DateTime, Hour, Minute, Second, MilliSecond);
  921. ResultLen := 0;
  922. ResultCurrent := @ResultBuffer[0];
  923. if FormatStr <> '' then
  924. StoreFormat(FormatStr, 0, False)
  925. else
  926. StoreFormat('C', 0, False);
  927. ResultBuffer[ResultLen] := #0;
  928. result := StrPas(@ResultBuffer[0]);
  929. end ;
  930. Function DateTimeToFileDate(DateTime : TDateTime) : Longint;
  931. Var YY,MM,DD,H,m,s,msec : Word;
  932. begin
  933. Decodedate (DateTime,YY,MM,DD);
  934. DecodeTime (DateTime,h,m,s,msec);
  935. {$ifndef unix}
  936. If (YY<1980) or (YY>2099) then
  937. Result:=0
  938. else
  939. begin
  940. Result:=(s shr 1) or (m shl 5) or (h shl 11);
  941. Result:=Result or longint(DD shl 16 or (MM shl 21) or (word(YY-1980) shl 25));
  942. end;
  943. {$else unix}
  944. Result:=LocalToEpoch(yy,mm,dd,h,m,s);
  945. {$endif unix}
  946. end;
  947. function CurrentYear: Word;
  948. var
  949. SysTime: TSystemTime;
  950. begin
  951. GetLocalTime(SysTime);
  952. Result := SysTime.Year;
  953. end;
  954. Function FileDateToDateTime (Filedate : Longint) : TDateTime;
  955. {$ifndef unix}
  956. Var Date,Time : Word;
  957. begin
  958. Date:=FileDate shr 16;
  959. Time:=FileDate and $ffff;
  960. Result:=ComposeDateTime(EncodeDate((Date shr 9) + 1980,(Date shr 5) and 15, Date and 31),
  961. EncodeTime(Time shr 11, (Time shr 5) and 63, (Time and 31) shl 1,0));
  962. end;
  963. {$else unix}
  964. var
  965. y, mon, d, h, min, s: word;
  966. begin
  967. EpochToLocal(FileDate,y,mon,d,h,min,s);
  968. Result:=ComposeDateTime(EncodeDate(y,mon,d),EncodeTime(h,min,s,0));
  969. end;
  970. {$endif unix}
  971. function TryStrToDate(const S: ShortString; out Value: TDateTime): Boolean;
  972. begin
  973. result := TryStrToDate(S, Value, #0);
  974. end;
  975. function TryStrToDate(const S: ShortString; out Value: TDateTime;
  976. const useformat : string; separator : char = #0): Boolean;
  977. Var
  978. Msg : Ansistring;
  979. begin
  980. Value:=IntStrToDate(Msg,@S[1],Length(S),useformat,defaultformatsettings,separator);
  981. Result:=(Msg='');
  982. end;
  983. function TryStrToDate(const S: AnsiString; out Value: TDateTime;
  984. const useformat : string; separator : char = #0): Boolean;
  985. Var
  986. Msg : Ansistring;
  987. begin
  988. Result:=Length(S)<>0;
  989. If Result then
  990. begin
  991. Value:=IntStrToDate(Msg,@S[1],Length(S),useformat,DefaultFormatSettings,Separator);
  992. Result:=(Msg='');
  993. end;
  994. end;
  995. function TryStrToDate(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
  996. begin
  997. Result:=TryStrToDate(S,Value,ShortDateFormat,Separator);
  998. end;
  999. function TryStrToDate(const S: AnsiString; out Value: TDateTime): Boolean;
  1000. begin
  1001. Result:=TryStrToDate(S,Value,ShortDateFormat,#0);
  1002. end;
  1003. function TryStrToDate(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
  1004. begin
  1005. Result:=TryStrToDate(S,Value,ShortDateFormat,Separator);
  1006. end;
  1007. function TryStrToDate(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
  1008. Var
  1009. Msg : Ansistring;
  1010. begin
  1011. Result:=Length(S)<>0;
  1012. If Result then
  1013. begin
  1014. Value:=IntStrToDate(Msg,@S[1],Length(S),FormatSettings.ShortDateFormat,FormatSettings,#0);
  1015. Result:=(Msg='');
  1016. end;
  1017. end;
  1018. function TryStrToTime(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
  1019. Var
  1020. Msg : AnsiString;
  1021. begin
  1022. Value:=IntStrToTime(Msg,@S[1],Length(S),DefaultFormatSettings,Separator);
  1023. result:=(Msg='');
  1024. end;
  1025. function TryStrToTime(const S: ShortString; out Value: TDateTime): Boolean;
  1026. begin
  1027. Result := TryStrToTime(S,Value,#0);
  1028. end;
  1029. function TryStrToTime(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
  1030. Var
  1031. Msg : AnsiString;
  1032. begin
  1033. Result:=Length(S)<>0;
  1034. If Result then
  1035. begin
  1036. Value:=IntStrToTime(Msg,@S[1],Length(S),DefaultFormatSettings,Separator);
  1037. Result:=(Msg='');
  1038. end;
  1039. end;
  1040. function TryStrToTime(const S: AnsiString; out Value: TDateTime): Boolean;
  1041. begin
  1042. result := TryStrToTime(S,Value,#0);
  1043. end;
  1044. function TryStrToTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
  1045. Var msg : AnsiString;
  1046. begin
  1047. Result:=Length(S)<>0;
  1048. If Result then
  1049. begin
  1050. Value:=IntStrToTime(Msg,@S[1],Length(S),FormatSettings,#0);
  1051. Result:=(Msg='');
  1052. end;
  1053. end;
  1054. function TryStrToDateTime(const S: ShortString; out Value: TDateTime): Boolean;
  1055. begin
  1056. result:=true;
  1057. try
  1058. value:=StrToDateTime(s);
  1059. except
  1060. on EConvertError do
  1061. result:=false
  1062. end;
  1063. end;
  1064. function TryStrToDateTime(const S: AnsiString; out Value: TDateTime): Boolean;
  1065. begin
  1066. result:=true;
  1067. try
  1068. value:=StrToDateTime(s);
  1069. except
  1070. on EConvertError do
  1071. result:=false
  1072. end;
  1073. end;
  1074. function TryStrToDateTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
  1075. var
  1076. I: integer;
  1077. dtdate, dttime :TDateTime;
  1078. begin
  1079. result:=true;
  1080. I:=Pos(FormatSettings.TimeSeparator,S);
  1081. If (I>0) then
  1082. begin
  1083. While (I>0) and (S[I]<>' ') do
  1084. Dec(I);
  1085. If I>0 then
  1086. begin
  1087. if not TryStrToDate(Copy(S,1,I-1),dtdate,Formatsettings) then
  1088. exit;
  1089. if not TryStrToTime(Copy(S,i+1, Length(S)-i),dttime,Formatsettings) then
  1090. exit;
  1091. Value:=ComposeDateTime(dtdate,dttime);
  1092. end
  1093. else
  1094. result:=TryStrToTime(s,Value,Formatsettings);
  1095. end
  1096. else
  1097. result:=TryStrToDate(s,Value,Formatsettings);
  1098. end;
  1099. function StrToDateDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
  1100. begin
  1101. result := StrToDateDef(S,DefValue,#0);
  1102. end;
  1103. function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
  1104. begin
  1105. result := StrToTimeDef(S,DefValue,#0);
  1106. end;
  1107. function StrToDateTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
  1108. begin
  1109. if not TryStrToDateTime(s,Result) Then
  1110. result:=defvalue;
  1111. end;
  1112. function StrToDateDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
  1113. begin
  1114. if not TryStrToDate(s,Result, separator) Then
  1115. result:=defvalue;
  1116. end;
  1117. function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
  1118. begin
  1119. if not TryStrToTime(s,Result, separator) Then
  1120. result:=defvalue;
  1121. end;
  1122. function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
  1123. begin
  1124. result := StrToDateDef(S,DefValue,#0);
  1125. end;
  1126. function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
  1127. begin
  1128. result := StrToTimeDef(S,DefValue,#0);
  1129. end;
  1130. function StrToDateTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
  1131. begin
  1132. if not TryStrToDateTime(s,Result) Then
  1133. result:=defvalue;
  1134. end;
  1135. function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime;
  1136. begin
  1137. if not TryStrToDate(s,Result, separator) Then
  1138. result:=defvalue;
  1139. end;
  1140. function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime;
  1141. begin
  1142. if not TryStrToTime(s,Result, separator) Then
  1143. result:=defvalue;
  1144. end;
  1145. procedure ReplaceTime(var dati:TDateTime; NewTime : TDateTime);inline;
  1146. begin
  1147. dati:= ComposeDateTime(dati, newtime);
  1148. end;
  1149. procedure ReplaceDate(var DateTime: TDateTime; const NewDate: TDateTime); inline;
  1150. var
  1151. tmp : TDateTime;
  1152. begin
  1153. tmp:=NewDate;
  1154. ReplaceTime(tmp,DateTime);
  1155. DateTime:=tmp;
  1156. end;