dati.inc 40 KB

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