dateutil.inc 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058
  1. {$mode objfpc}
  2. {$h+}
  3. {
  4. $Id$
  5. This file is part of the Free Pascal run time library.
  6. Copyright (c) 1999-2000 by the Free Pascal development team
  7. Delphi/Kylix compatibility unit, provides Date/Time handling routines.
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit dateutils;
  15. interface
  16. uses
  17. SysUtils, Math, Types;
  18. { ---------------------------------------------------------------------
  19. Various constants
  20. ---------------------------------------------------------------------}
  21. const
  22. DaysPerWeek = 7;
  23. WeeksPerFortnight = 2;
  24. MonthsPerYear = 12;
  25. YearsPerDecade = 10;
  26. YearsPerCentury = 100;
  27. YearsPerMillennium = 1000;
  28. // ISO day numbers.
  29. DayMonday = 1;
  30. DayTuesday = 2;
  31. DayWednesday = 3;
  32. DayThursday = 4;
  33. DayFriday = 5;
  34. DaySaturday = 6;
  35. DaySunday = 7;
  36. // Fraction of a day
  37. OneHour = 1/HoursPerDay;
  38. OneMinute = 1/MinsPerDay;
  39. OneSecond = 1/SecsPerDay;
  40. OneMillisecond = 1/MSecsPerDay;
  41. { This is actual days per year but you need to know if it's a leap year}
  42. DaysPerYear: array [Boolean] of Word = (365, 366);
  43. { Used in RecodeDate, RecodeTime and RecodeDateTime for those datetime }
  44. { fields you want to leave alone }
  45. RecodeLeaveFieldAsIs = High(Word);
  46. { ---------------------------------------------------------------------
  47. Global variables used in this unit
  48. ---------------------------------------------------------------------}
  49. Const
  50. { Average over a 4 year span. Valid for next 100 years }
  51. ApproxDaysPerMonth: Double = 30.4375;
  52. ApproxDaysPerYear: Double = 365.25;
  53. { ---------------------------------------------------------------------
  54. Simple trimming functions.
  55. ---------------------------------------------------------------------}
  56. Function DateOf(const AValue: TDateTime): TDateTime;
  57. Function TimeOf(const AValue: TDateTime): TDateTime;
  58. { ---------------------------------------------------------------------
  59. Identification functions.
  60. ---------------------------------------------------------------------}
  61. Function IsInLeapYear(const AValue: TDateTime): Boolean;
  62. Function IsPM(const AValue: TDateTime): Boolean;
  63. Function IsValidDate(const AYear, AMonth, ADay: Word): Boolean;
  64. Function IsValidTime(const AHour, AMinute, ASecond, AMilliSecond: Word): Boolean;
  65. Function IsValidDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): Boolean;
  66. Function IsValidDateDay(const AYear, ADayOfYear: Word): Boolean;
  67. Function IsValidDateWeek(const AYear, AWeekOfYear, ADayOfWeek: Word): Boolean;
  68. Function IsValidDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word): Boolean;
  69. { ---------------------------------------------------------------------
  70. Enumeration functions.
  71. ---------------------------------------------------------------------}
  72. Function WeeksInYear(const AValue: TDateTime): Word;
  73. Function WeeksInAYear(const AYear: Word): Word;
  74. Function DaysInYear(const AValue: TDateTime): Word;
  75. Function DaysInAYear(const AYear: Word): Word;
  76. Function DaysInMonth(const AValue: TDateTime): Word;
  77. Function DaysInAMonth(const AYear, AMonth: Word): Word;
  78. { ---------------------------------------------------------------------
  79. Variations on current date/time.
  80. ---------------------------------------------------------------------}
  81. Function Today: TDateTime;
  82. Function Yesterday: TDateTime;
  83. Function Tomorrow: TDateTime;
  84. Function IsToday(const AValue: TDateTime): Boolean;
  85. Function IsSameDay(const AValue, ABasis: TDateTime): Boolean;
  86. Function PreviousDayOfWeek (DayOfWeek : Word) : Word;
  87. { ---------------------------------------------------------------------
  88. Extraction functions.
  89. ---------------------------------------------------------------------}
  90. Function YearOf(const AValue: TDateTime): Word;
  91. Function MonthOf(const AValue: TDateTime): Word;
  92. Function WeekOf(const AValue: TDateTime): Word;
  93. Function DayOf(const AValue: TDateTime): Word;
  94. Function HourOf(const AValue: TDateTime): Word;
  95. Function MinuteOf(const AValue: TDateTime): Word;
  96. Function SecondOf(const AValue: TDateTime): Word;
  97. Function MilliSecondOf(const AValue: TDateTime): Word;
  98. { ---------------------------------------------------------------------
  99. Start/End of year functions.
  100. ---------------------------------------------------------------------}
  101. Function StartOfTheYear(const AValue: TDateTime): TDateTime;
  102. Function EndOfTheYear(const AValue: TDateTime): TDateTime;
  103. Function StartOfAYear(const AYear: Word): TDateTime;
  104. Function EndOfAYear(const AYear: Word): TDateTime;
  105. { ---------------------------------------------------------------------
  106. Start/End of month functions.
  107. ---------------------------------------------------------------------}
  108. Function StartOfTheMonth(const AValue: TDateTime): TDateTime;
  109. Function EndOfTheMonth(const AValue: TDateTime): TDateTime;
  110. Function StartOfAMonth(const AYear, AMonth: Word): TDateTime;
  111. Function EndOfAMonth(const AYear, AMonth: Word): TDateTime;
  112. { ---------------------------------------------------------------------
  113. Start/End of week functions.
  114. ---------------------------------------------------------------------}
  115. Function StartOfTheWeek(const AValue: TDateTime): TDateTime;
  116. Function EndOfTheWeek(const AValue: TDateTime): TDateTime;
  117. Function StartOfAWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  118. Function StartOfAWeek(const AYear, AWeekOfYear: Word): TDateTime; // ADayOFWeek 1
  119. Function EndOfAWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  120. Function EndOfAWeek(const AYear, AWeekOfYear: Word): TDateTime; // const ADayOfWeek: Word = 7
  121. { ---------------------------------------------------------------------
  122. Start/End of day functions.
  123. ---------------------------------------------------------------------}
  124. Function StartOfTheDay(const AValue: TDateTime): TDateTime;
  125. Function EndOfTheDay(const AValue: TDateTime): TDateTime;
  126. Function StartOfADay(const AYear, AMonth, ADay: Word): TDateTime; overload;
  127. Function StartOfADay(const AYear, ADayOfYear: Word): TDateTime; overload;
  128. Function EndOfADay(const AYear, AMonth, ADay: Word): TDateTime; overload;
  129. Function EndOfADay(const AYear, ADayOfYear: Word): TDateTime; overload;
  130. { ---------------------------------------------------------------------
  131. Part of year functions.
  132. ---------------------------------------------------------------------}
  133. Function MonthOfTheYear(const AValue: TDateTime): Word;
  134. Function WeekOfTheYear(const AValue: TDateTime): Word; overload;
  135. Function WeekOfTheYear(const AValue: TDateTime; var AYear: Word): Word; overload;
  136. Function DayOfTheYear(const AValue: TDateTime): Word;
  137. Function HourOfTheYear(const AValue: TDateTime): Word;
  138. Function MinuteOfTheYear(const AValue: TDateTime): LongWord;
  139. Function SecondOfTheYear(const AValue: TDateTime): LongWord;
  140. Function MilliSecondOfTheYear(const AValue: TDateTime): Int64;
  141. { ---------------------------------------------------------------------
  142. Part of month functions.
  143. ---------------------------------------------------------------------}
  144. Function WeekOfTheMonth(const AValue: TDateTime): Word; overload;
  145. Function WeekOfTheMonth(const AValue: TDateTime; var AYear, AMonth: Word): Word; overload;
  146. Function DayOfTheMonth(const AValue: TDateTime): Word;
  147. Function HourOfTheMonth(const AValue: TDateTime): Word;
  148. Function MinuteOfTheMonth(const AValue: TDateTime): Word;
  149. Function SecondOfTheMonth(const AValue: TDateTime): LongWord;
  150. Function MilliSecondOfTheMonth(const AValue: TDateTime): LongWord;
  151. { ---------------------------------------------------------------------
  152. Part of week functions.
  153. ---------------------------------------------------------------------}
  154. Function DayOfTheWeek(const AValue: TDateTime): Word;
  155. Function HourOfTheWeek(const AValue: TDateTime): Word;
  156. Function MinuteOfTheWeek(const AValue: TDateTime): Word;
  157. Function SecondOfTheWeek(const AValue: TDateTime): LongWord;
  158. Function MilliSecondOfTheWeek(const AValue: TDateTime): LongWord;
  159. { ---------------------------------------------------------------------
  160. Part of day functions.
  161. ---------------------------------------------------------------------}
  162. Function HourOfTheDay(const AValue: TDateTime): Word;
  163. Function MinuteOfTheDay(const AValue: TDateTime): Word;
  164. Function SecondOfTheDay(const AValue: TDateTime): LongWord;
  165. Function MilliSecondOfTheDay(const AValue: TDateTime): LongWord;
  166. { ---------------------------------------------------------------------
  167. Part of hour functions.
  168. ---------------------------------------------------------------------}
  169. Function MinuteOfTheHour(const AValue: TDateTime): Word;
  170. Function SecondOfTheHour(const AValue: TDateTime): Word;
  171. Function MilliSecondOfTheHour(const AValue: TDateTime): LongWord;
  172. { ---------------------------------------------------------------------
  173. Part of minute functions.
  174. ---------------------------------------------------------------------}
  175. Function SecondOfTheMinute(const AValue: TDateTime): Word;
  176. Function MilliSecondOfTheMinute(const AValue: TDateTime): LongWord;
  177. { ---------------------------------------------------------------------
  178. Part of second functions.
  179. ---------------------------------------------------------------------}
  180. Function MilliSecondOfTheSecond(const AValue: TDateTime): Word;
  181. { ---------------------------------------------------------------------
  182. Range checking functions.
  183. ---------------------------------------------------------------------}
  184. Function WithinPastYears(const ANow, AThen: TDateTime; const AYears: Integer): Boolean;
  185. Function WithinPastMonths(const ANow, AThen: TDateTime; const AMonths: Integer): Boolean;
  186. Function WithinPastWeeks(const ANow, AThen: TDateTime; const AWeeks: Integer): Boolean;
  187. Function WithinPastDays(const ANow, AThen: TDateTime; const ADays: Integer): Boolean;
  188. Function WithinPastHours(const ANow, AThen: TDateTime; const AHours: Int64): Boolean;
  189. Function WithinPastMinutes(const ANow, AThen: TDateTime; const AMinutes: Int64): Boolean;
  190. Function WithinPastSeconds(const ANow, AThen: TDateTime; const ASeconds: Int64): Boolean;
  191. Function WithinPastMilliSeconds(const ANow, AThen: TDateTime; const AMilliSeconds: Int64): Boolean;
  192. { ---------------------------------------------------------------------
  193. Period functions.
  194. ---------------------------------------------------------------------}
  195. Function YearsBetween(const ANow, AThen: TDateTime): Integer;
  196. Function MonthsBetween(const ANow, AThen: TDateTime): Integer;
  197. Function WeeksBetween(const ANow, AThen: TDateTime): Integer;
  198. Function DaysBetween(const ANow, AThen: TDateTime): Integer;
  199. Function HoursBetween(const ANow, AThen: TDateTime): Int64;
  200. Function MinutesBetween(const ANow, AThen: TDateTime): Int64;
  201. Function SecondsBetween(const ANow, AThen: TDateTime): Int64;
  202. Function MilliSecondsBetween(const ANow, AThen: TDateTime): Int64;
  203. { ---------------------------------------------------------------------
  204. Timespan in xxx functions.
  205. ---------------------------------------------------------------------}
  206. { YearSpan and MonthSpan are approximate values }
  207. Function YearSpan(const ANow, AThen: TDateTime): Double;
  208. Function MonthSpan(const ANow, AThen: TDateTime): Double;
  209. Function WeekSpan(const ANow, AThen: TDateTime): Double;
  210. Function DaySpan(const ANow, AThen: TDateTime): Double;
  211. Function HourSpan(const ANow, AThen: TDateTime): Double;
  212. Function MinuteSpan(const ANow, AThen: TDateTime): Double;
  213. Function SecondSpan(const ANow, AThen: TDateTime): Double;
  214. Function MilliSecondSpan(const ANow, AThen: TDateTime): Double;
  215. { ---------------------------------------------------------------------
  216. Increment/decrement functions.
  217. ---------------------------------------------------------------------}
  218. Function IncYear(const AValue: TDateTime; const ANumberOfYears: Integer ): TDateTime;
  219. Function IncYear(const AValue: TDateTime): TDateTime; // ; const ANumberOfYears: Integer = 1)
  220. // Function IncMonth is in SysUtils
  221. Function IncWeek(const AValue: TDateTime; const ANumberOfWeeks: Integer): TDateTime;
  222. Function IncWeek(const AValue: TDateTime): TDateTime; // ; const ANumberOfWeeks: Integer = 1)
  223. Function IncDay(const AValue: TDateTime; const ANumberOfDays: Integer): TDateTime;
  224. Function IncDay(const AValue: TDateTime): TDateTime; //; const ANumberOfDays: Integer = 1)
  225. Function IncHour(const AValue: TDateTime; const ANumberOfHours: Int64): TDateTime;
  226. Function IncHour(const AValue: TDateTime): TDateTime; //; const ANumberOfHours: Int64 = 1
  227. Function IncMinute(const AValue: TDateTime; const ANumberOfMinutes: Int64): TDateTime;
  228. Function IncMinute(const AValue: TDateTime): TDateTime; // ; const ANumberOfMinutes: Int64 = 1
  229. Function IncSecond(const AValue: TDateTime; const ANumberOfSeconds: Int64): TDateTime;
  230. Function IncSecond(const AValue: TDateTime): TDateTime; // ; const ANumberOfSeconds: Int64 = 1
  231. Function IncMilliSecond(const AValue: TDateTime; const ANumberOfMilliSeconds: Int64): TDateTime;
  232. Function IncMilliSecond(const AValue: TDateTime): TDateTime; // ; const ANumberOfMilliSeconds: Int64 = 1
  233. { ---------------------------------------------------------------------
  234. Encode/Decode of complete timestamp
  235. ---------------------------------------------------------------------}
  236. Function EncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  237. Procedure DecodeDateTime(const AValue: TDateTime; var AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
  238. Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AValue: TDateTime): Boolean;
  239. { ---------------------------------------------------------------------
  240. Encode/decode date, specifying week of year and day of week
  241. ---------------------------------------------------------------------}
  242. Function EncodeDateWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  243. Function EncodeDateWeek(const AYear, AWeekOfYear: Word): TDateTime; //; const ADayOfWeek: Word = 1
  244. Procedure DecodeDateWeek(const AValue: TDateTime; var AYear, AWeekOfYear, ADayOfWeek: Word);
  245. Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime; const ADayOfWeek: Word): Boolean;
  246. Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
  247. { ---------------------------------------------------------------------
  248. Encode/decode date, specifying day of year
  249. ---------------------------------------------------------------------}
  250. Function EncodeDateDay(const AYear, ADayOfYear: Word): TDateTime;
  251. Procedure DecodeDateDay(const AValue: TDateTime; var AYear, ADayOfYear: Word);
  252. Function TryEncodeDateDay(const AYear, ADayOfYear: Word; var AValue: TDateTime): Boolean;
  253. { ---------------------------------------------------------------------
  254. Encode/decode date, specifying week of month
  255. ---------------------------------------------------------------------}
  256. Function EncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word): TDateTime;
  257. Procedure DecodeDateMonthWeek(const AValue: TDateTime; var AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
  258. Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
  259. { ---------------------------------------------------------------------
  260. Replace given element with supplied value.
  261. ---------------------------------------------------------------------}
  262. Function RecodeYear(const AValue: TDateTime; const AYear: Word): TDateTime;
  263. Function RecodeMonth(const AValue: TDateTime; const AMonth: Word): TDateTime;
  264. Function RecodeDay(const AValue: TDateTime; const ADay: Word): TDateTime;
  265. Function RecodeHour(const AValue: TDateTime; const AHour: Word): TDateTime;
  266. Function RecodeMinute(const AValue: TDateTime; const AMinute: Word): TDateTime;
  267. Function RecodeSecond(const AValue: TDateTime; const ASecond: Word): TDateTime;
  268. Function RecodeMilliSecond(const AValue: TDateTime; const AMilliSecond: Word): TDateTime;
  269. Function RecodeDate(const AValue: TDateTime; const AYear, AMonth, ADay: Word): TDateTime;
  270. Function RecodeTime(const AValue: TDateTime; const AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  271. Function RecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  272. Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AResult: TDateTime): Boolean;
  273. { ---------------------------------------------------------------------
  274. Comparision of date/time
  275. ---------------------------------------------------------------------}
  276. Function CompareDateTime(const A, B: TDateTime): TValueRelationship;
  277. Function CompareDate(const A, B: TDateTime): TValueRelationship;
  278. Function CompareTime(const A, B: TDateTime): TValueRelationship;
  279. Function SameDateTime(const A, B: TDateTime): Boolean;
  280. Function SameDate(const A, B: TDateTime): Boolean;
  281. Function SameTime(const A, B: TDateTime): Boolean;
  282. { For a given date these Functions tell you the which day of the week of the
  283. month (or year). If its a Thursday, they will tell you if its the first,
  284. second, etc Thursday of the month (or year). Remember, even though its
  285. the first Thursday of the year it doesn't mean its the first week of the
  286. year. See ISO 8601 above for more information. }
  287. Function NthDayOfWeek(const AValue: TDateTime): Word;
  288. Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; var AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
  289. Function EncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word): TDateTime;
  290. Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
  291. { ---------------------------------------------------------------------
  292. Exception throwing routines
  293. ---------------------------------------------------------------------}
  294. Procedure InvalidDateTimeError(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; const ABaseDate: TDateTime);
  295. Procedure InvalidDateTimeError(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word); // const ABaseDate: TDateTime = 0
  296. Procedure InvalidDateWeekError(const AYear, AWeekOfYear, ADayOfWeek: Word);
  297. Procedure InvalidDateDayError(const AYear, ADayOfYear: Word);
  298. Procedure InvalidDateMonthWeekError(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
  299. Procedure InvalidDayOfWeekInMonthError(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
  300. { ---------------------------------------------------------------------
  301. Julian and Modified Julian Date conversion support
  302. ---------------------------------------------------------------------}
  303. Function DateTimeToJulianDate(const AValue: TDateTime): Double;
  304. Function JulianDateToDateTime(const AValue: Double): TDateTime;
  305. Function TryJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
  306. Function DateTimeToModifiedJulianDate(const AValue: TDateTime): Double;
  307. Function ModifiedJulianDateToDateTime(const AValue: Double): TDateTime;
  308. Function TryModifiedJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
  309. { ---------------------------------------------------------------------
  310. Unix timestamp support.
  311. ---------------------------------------------------------------------}
  312. Function DateTimeToUnix(const AValue: TDateTime): Int64;
  313. Function UnixToDateTime(const AValue: Int64): TDateTime;
  314. implementation
  315. uses sysconst;
  316. { ---------------------------------------------------------------------
  317. Auxiliary routines
  318. ---------------------------------------------------------------------}
  319. Procedure NotYetImplemented (FN : String);
  320. begin
  321. Raise Exception.CreateFmt('Function "%s" (dateutils) is not yet implemented',[FN]);
  322. end;
  323. { ---------------------------------------------------------------------
  324. Simple trimming functions.
  325. ---------------------------------------------------------------------}
  326. Function DateOf(const AValue: TDateTime): TDateTime;
  327. begin
  328. Result:=Trunc(AValue);
  329. end;
  330. Function TimeOf(const AValue: TDateTime): TDateTime;
  331. begin
  332. Result:=Frac(Avalue);
  333. end;
  334. { ---------------------------------------------------------------------
  335. Identification functions.
  336. ---------------------------------------------------------------------}
  337. Function IsInLeapYear(const AValue: TDateTime): Boolean;
  338. Var
  339. D,Y,M : Word;
  340. begin
  341. DecodeDate(AValue,Y,M,D);
  342. Result:=IsLeapYear(Y);
  343. end;
  344. Function IsPM(const AValue: TDateTime): Boolean;
  345. Var
  346. H,M,S,MS : Word;
  347. begin
  348. DecodeTime(AValue,H,M,S,MS);
  349. Result:=(H>=12);
  350. end;
  351. Function IsValidDate(const AYear, AMonth, ADay: Word): Boolean;
  352. begin
  353. Result:=(AYear<>0) and (AYear<10000)
  354. and (AMonth in [1..12])
  355. and (ADay<>0) and (ADay<=MonthDays[IsleapYear(AYear),AMonth]);
  356. end;
  357. Function IsValidTime(const AHour, AMinute, ASecond, AMilliSecond: Word): Boolean;
  358. begin
  359. Result:=(AHour=HoursPerDay) and (AMinute=0) and (ASecond=0) and (AMillisecond=0);
  360. Result:=Result or
  361. ((AHour<HoursPerDay) and (AMinute<MinsPerHour) and (ASecond<SecsPerMin) and
  362. (AMillisecond<MSecsPerSec));
  363. end;
  364. Function IsValidDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): Boolean;
  365. begin
  366. Result:=IsValidDate(AYear,AMonth,ADay) and
  367. IsValidTime(AHour,AMinute,ASecond,AMillisecond)
  368. end;
  369. Function IsValidDateDay(const AYear, ADayOfYear: Word): Boolean;
  370. begin
  371. Result:=(AYear<>0) and (ADayOfYear<>0) and (AYear<10000) and
  372. (ADayOfYear<=DaysPerYear[IsLeapYear(AYear)]);
  373. end;
  374. Function IsValidDateWeek(const AYear, AWeekOfYear, ADayOfWeek: Word): Boolean;
  375. begin
  376. Result:=(AYear<>0) and (AYear<10000)
  377. and (ADayOfWeek in [1..7])
  378. and (AWeekOfYear<>0)
  379. and (AWeekOfYear<=WeeksInaYear(AYear));
  380. { should we not also check whether the day of the week is not
  381. larger than the last day of the last week in the year 9999 ?? }
  382. end;
  383. Function IsValidDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word): Boolean;
  384. begin
  385. Result:=(AYear<>0) and (AYear<10000)
  386. and (AMonth in [1..12])
  387. and (AWeekOfMonth in [1..5])
  388. and (ADayOfWeek in [1..7]);
  389. end;
  390. { ---------------------------------------------------------------------
  391. Enumeration functions.
  392. ---------------------------------------------------------------------}
  393. Function WeeksInYear(const AValue: TDateTime): Word;
  394. Var
  395. Y,M,D : Word;
  396. begin
  397. DecodeDate(AValue,Y,M,D);
  398. Result:=WeeksInAYear(Y);
  399. end;
  400. Function WeeksInAYear(const AYear: Word): Word;
  401. Var
  402. DOW : Word;
  403. begin
  404. Result:=52;
  405. DOW:=DayOfTheWeek(StartOfAYear(AYear));
  406. If (DOW=4) or ((DOW=3) and IsLeapYear(AYear)) then
  407. Inc(Result);
  408. end;
  409. Function DaysInYear(const AValue: TDateTime): Word;
  410. Var
  411. Y,M,D : Word;
  412. begin
  413. DecodeDate(AValue,Y,M,D);
  414. Result:=DaysPerYear[IsLeapYear(Y)];
  415. end;
  416. Function DaysInAYear(const AYear: Word): Word;
  417. begin
  418. Result:=DaysPerYear[Isleapyear(AYear)];
  419. end;
  420. Function DaysInMonth(const AValue: TDateTime): Word;
  421. Var
  422. Y,M,D : Word;
  423. begin
  424. Decodedate(AValue,Y,M,D);
  425. Result:=MonthDays[IsLeapYear(Y),M];
  426. end;
  427. Function DaysInAMonth(const AYear, AMonth: Word): Word;
  428. begin
  429. Result:=MonthDays[IsLeapYear(AYear),AMonth];
  430. end;
  431. { ---------------------------------------------------------------------
  432. Variations on current date/time.
  433. ---------------------------------------------------------------------}
  434. Function Today: TDateTime;
  435. begin
  436. Result:=Date;
  437. end;
  438. Function Yesterday: TDateTime;
  439. begin
  440. Result:=Date-1;
  441. end;
  442. Function Tomorrow: TDateTime;
  443. begin
  444. Result:=Date+1;
  445. end;
  446. Function IsToday(const AValue: TDateTime): Boolean;
  447. begin
  448. Result:=IsSameDay(AValue,Date);
  449. end;
  450. Function IsSameDay(const AValue, ABasis: TDateTime): Boolean;
  451. Var
  452. D : TDateTime;
  453. begin
  454. D:=AValue-Trunc(ABasis);
  455. Result:=(D>=0) and (D<1);
  456. end;
  457. const
  458. DOWMap: array [1..7] of Word = (7, 1, 2, 3, 4, 5, 6);
  459. Function PreviousDayOfWeek (DayOfWeek : Word) : Word;
  460. begin
  461. If Not (DayOfWeek in [1..7]) then
  462. Raise EConvertError.CreateFmt(SErrInvalidDayOfWeek,[DayOfWeek]);
  463. Result:=DOWMap[DayOfWeek];
  464. end;
  465. { ---------------------------------------------------------------------
  466. Extraction functions.
  467. ---------------------------------------------------------------------}
  468. Function YearOf(const AValue: TDateTime): Word;
  469. Var
  470. D,M : Word;
  471. begin
  472. DecodeDate(AValue,Result,D,M);
  473. end;
  474. Function MonthOf(const AValue: TDateTime): Word;
  475. Var
  476. Y,D : Word;
  477. begin
  478. DecodeDate(AValue,Y,Result,D);
  479. end;
  480. Function WeekOf(const AValue: TDateTime): Word;
  481. begin
  482. Result:=WeekOfTheYear(AValue);
  483. end;
  484. Function DayOf(const AValue: TDateTime): Word;
  485. Var
  486. Y,M : Word;
  487. begin
  488. DecodeDate(AValue,Y,M,Result);
  489. end;
  490. Function HourOf(const AValue: TDateTime): Word;
  491. Var
  492. N,S,MS : Word;
  493. begin
  494. DecodeTime(AValue,Result,N,S,MS);
  495. end;
  496. Function MinuteOf(const AValue: TDateTime): Word;
  497. Var
  498. H,S,MS : Word;
  499. begin
  500. DecodeTime(AValue,H,Result,S,MS);
  501. end;
  502. Function SecondOf(const AValue: TDateTime): Word;
  503. Var
  504. H,N,MS : Word;
  505. begin
  506. DecodeTime(AVAlue,H,N,Result,MS);
  507. end;
  508. Function MilliSecondOf(const AValue: TDateTime): Word;
  509. Var
  510. H,N,S : Word;
  511. begin
  512. DecodeTime(AValue,H,N,S,Result);
  513. end;
  514. { ---------------------------------------------------------------------
  515. Start/End of year functions.
  516. ---------------------------------------------------------------------}
  517. Function StartOfTheYear(const AValue: TDateTime): TDateTime;
  518. Var
  519. Y,M,D : Word;
  520. begin
  521. DecodeDate(AValue,Y,M,D);
  522. Result:=EncodeDate(Y,1,1);
  523. end;
  524. Function EndOfTheYear(const AValue: TDateTime): TDateTime;
  525. Var
  526. Y,M,D : Word;
  527. begin
  528. DecodeDate(AValue,Y,M,D);
  529. Result:=EncodeDateTime(Y,12,31,23,59,59,999);
  530. end;
  531. Function StartOfAYear(const AYear: Word): TDateTime;
  532. begin
  533. Result:=EncodeDate(AYear,1,1);
  534. end;
  535. Function EndOfAYear(const AYear: Word): TDateTime;
  536. begin
  537. Result:=(EncodeDateTime(AYear,12,31,23,59,59,999));
  538. end;
  539. { ---------------------------------------------------------------------
  540. Start/End of month functions.
  541. ---------------------------------------------------------------------}
  542. Function StartOfTheMonth(const AValue: TDateTime): TDateTime;
  543. Var
  544. Y,M,D : Word;
  545. begin
  546. DecodeDate(AValue,Y,M,D);
  547. Result:=EncodeDate(Y,M,1);
  548. // MonthDays[IsLeapYear(Y),M])
  549. end;
  550. Function EndOfTheMonth(const AValue: TDateTime): TDateTime;
  551. Var
  552. Y,M,D : Word;
  553. begin
  554. DecodeDate(AValue,Y,M,D);
  555. Result:=EncodeDateTime(Y,M,MonthDays[IsLeapYear(Y),M],23,59,59,999);
  556. end;
  557. Function StartOfAMonth(const AYear, AMonth: Word): TDateTime;
  558. begin
  559. Result:=EncodeDate(AYear,AMonth,1);
  560. end;
  561. Function EndOfAMonth(const AYear, AMonth: Word): TDateTime;
  562. begin
  563. Result:=EncodeDateTime(AYear,AMonth,MonthDays[IsLeapYear(AYear),AMonth],23,59,59,999);
  564. end;
  565. { ---------------------------------------------------------------------
  566. Start/End of week functions.
  567. ---------------------------------------------------------------------}
  568. Function StartOfTheWeek(const AValue: TDateTime): TDateTime;
  569. begin
  570. Result:=Trunc(AValue)-DayOfTheWeek(AValue)+1;
  571. end;
  572. Function EndOfTheWeek(const AValue: TDateTime): TDateTime;
  573. begin
  574. Result:=EndOfTheDay(AValue-DayOfTheWeek(AValue)+7);
  575. end;
  576. Function StartOfAWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  577. begin
  578. Result:=EncodeDateWeek(AYear,AWeekOfYear,ADayOfWeek);
  579. end;
  580. Function StartOfAWeek(const AYear, AWeekOfYear: Word): TDateTime; // ADayOFWeek 1
  581. begin
  582. Result:=StartOfAWeek(AYear,AWeekOfYear,1)
  583. end;
  584. Function EndOfAWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  585. begin
  586. Result := EndOfTheDay(EncodeDateWeek(AYear, AWeekOfYear, ADayOfWeek));
  587. end;
  588. Function EndOfAWeek(const AYear, AWeekOfYear: Word): TDateTime; // const ADayOfWeek: Word = 7
  589. begin
  590. Result:=EndOfAWeek(AYear,AWeekOfYear,7);
  591. end;
  592. { ---------------------------------------------------------------------
  593. Start/End of day functions.
  594. ---------------------------------------------------------------------}
  595. Function StartOfTheDay(const AValue: TDateTime): TDateTime;
  596. begin
  597. StartOfTheDay:=Trunc(Avalue);
  598. end;
  599. Function EndOfTheDay(const AValue: TDateTime): TDateTime;
  600. Var
  601. Y,M,D : Word;
  602. begin
  603. DecodeDate(AValue,Y,M,D);
  604. Result:=EncodeDateTime(Y,M,D,23,59,59,999);
  605. end;
  606. Function StartOfADay(const AYear, AMonth, ADay: Word): TDateTime;
  607. begin
  608. Result:=EncodeDate(AYear,AMonth,ADay);
  609. end;
  610. Function StartOfADay(const AYear, ADayOfYear: Word): TDateTime;
  611. begin
  612. Result:=StartOfAYear(AYear)+ADayOfYear-1;
  613. end;
  614. Function EndOfADay(const AYear, AMonth, ADay: Word): TDateTime;
  615. begin
  616. Result:=EndOfTheDay(EncodeDate(AYear,AMonth,ADay));
  617. end;
  618. Function EndOfADay(const AYear, ADayOfYear: Word): TDateTime;
  619. begin
  620. Result:=StartOfAYear(AYear)+ADayOfYear-1+EncodeTime(23,59,59,999);
  621. end;
  622. { ---------------------------------------------------------------------
  623. Part of year functions.
  624. ---------------------------------------------------------------------}
  625. Function MonthOfTheYear(const AValue: TDateTime): Word;
  626. Var
  627. Y,D : Word;
  628. begin
  629. DecodeDate(AValue,Y,Result,D);
  630. end;
  631. Function WeekOfTheYear(const AValue: TDateTime): Word;
  632. Var
  633. Y,DOW : Word;
  634. begin
  635. DecodeDateWeek(AValue,Y,Result,DOW)
  636. end;
  637. Function WeekOfTheYear(const AValue: TDateTime; var AYear: Word): Word;
  638. Var
  639. DOW : Word;
  640. begin
  641. DecodeDateWeek(AValue,AYear,Result,DOW);
  642. end;
  643. Function DayOfTheYear(const AValue: TDateTime): Word;
  644. begin
  645. Result:=Trunc(AValue-StartOfTheYear(AValue)+1);
  646. end;
  647. Function HourOfTheYear(const AValue: TDateTime): Word;
  648. Var
  649. H,M,S,MS : Word;
  650. begin
  651. DecodeTime(AValue,H,M,S,MS);
  652. Result:=H+((DayOfTheYear(AValue)-1)*24);
  653. end;
  654. Function MinuteOfTheYear(const AValue: TDateTime): LongWord;
  655. Var
  656. H,M,S,MS : Word;
  657. begin
  658. DecodeTime(AValue,H,M,S,MS);
  659. Result:=M+(H+((DayOfTheYear(AValue)-1)*24))*60;
  660. end;
  661. Function SecondOfTheYear(const AValue: TDateTime): LongWord;
  662. Var
  663. H,M,S,MS : Word;
  664. begin
  665. DecodeTime(AValue,H,M,S,MS);
  666. Result:=(M+(H+((DayOfTheYear(AValue)-1)*24))*60)*60+S;
  667. end;
  668. Function MilliSecondOfTheYear(const AValue: TDateTime): Int64;
  669. Var
  670. H,M,S,MS : Word;
  671. begin
  672. DecodeTime(AValue,H,M,S,MS);
  673. Result:=((M+(H+((DayOfTheYear(AValue)-1)*24))*60)*60+S)*1000+MS;
  674. end;
  675. { ---------------------------------------------------------------------
  676. Part of month functions.
  677. ---------------------------------------------------------------------}
  678. Function WeekOfTheMonth(const AValue: TDateTime): Word;
  679. var
  680. Y,M,DOW : word;
  681. begin
  682. DecodeDateMonthWeek(AValue,Y,M,Result,DOW);
  683. end;
  684. Function WeekOfTheMonth(const AValue: TDateTime; var AYear, AMonth: Word): Word;
  685. Var
  686. DOW : Word;
  687. begin
  688. DecodeDateMonthWeek(AValue,AYear,AMonth,Result,DOW);
  689. end;
  690. Function DayOfTheMonth(const AValue: TDateTime): Word;
  691. Var
  692. Y,M : Word;
  693. begin
  694. DecodeDate(AValue,Y,M,Result);
  695. end;
  696. Function HourOfTheMonth(const AValue: TDateTime): Word;
  697. Var
  698. Y,M,D,H,N,S,MS : Word;
  699. begin
  700. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  701. Result:=(D-1)*24+H;
  702. end;
  703. Function MinuteOfTheMonth(const AValue: TDateTime): Word;
  704. Var
  705. Y,M,D,H,N,S,MS : Word;
  706. begin
  707. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  708. Result:=((D-1)*24+H)*60+N;
  709. end;
  710. Function SecondOfTheMonth(const AValue: TDateTime): LongWord;
  711. Var
  712. Y,M,D,H,N,S,MS : Word;
  713. begin
  714. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  715. Result:=(((D-1)*24+H)*60+N)*60+S;
  716. end;
  717. Function MilliSecondOfTheMonth(const AValue: TDateTime): LongWord;
  718. Var
  719. Y,M,D,H,N,S,MS : Word;
  720. begin
  721. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  722. Result:=((((D-1)*24+H)*60+N)*60+S)*1000+MS;
  723. end;
  724. { ---------------------------------------------------------------------
  725. Part of week functions.
  726. ---------------------------------------------------------------------}
  727. Function DayOfTheWeek(const AValue: TDateTime): Word;
  728. begin
  729. Result:=DowMAP[DayOfWeek(AValue)];
  730. end;
  731. Function HourOfTheWeek(const AValue: TDateTime): Word;
  732. Var
  733. H,M,S,MS : Word;
  734. begin
  735. DecodeTime(AValue,H,M,S,MS);
  736. Result:=(DayOfTheWeek(AValue)-1)*24+H;
  737. end;
  738. Function MinuteOfTheWeek(const AValue: TDateTime): Word;
  739. Var
  740. H,M,S,MS : Word;
  741. begin
  742. DecodeTime(AValue,H,M,S,MS);
  743. Result:=((DayOfTheWeek(AValue)-1)*24+H)*60+M;
  744. end;
  745. Function SecondOfTheWeek(const AValue: TDateTime): LongWord;
  746. Var
  747. H,M,S,MS : Word;
  748. begin
  749. DecodeTime(AValue,H,M,S,MS);
  750. Result:=(((DayOfTheWeek(AValue)-1)*24+H)*60+M)*60+S;
  751. end;
  752. Function MilliSecondOfTheWeek(const AValue: TDateTime): LongWord;
  753. Var
  754. H,M,S,MS : Word;
  755. begin
  756. DecodeTime(AValue,H,M,S,MS);
  757. Result:=((((DayOfTheWeek(AValue)-1)*24+H)*60+M)*60+S)*1000+MS;
  758. end;
  759. { ---------------------------------------------------------------------
  760. Part of day functions.
  761. ---------------------------------------------------------------------}
  762. Function HourOfTheDay(const AValue: TDateTime): Word;
  763. Var
  764. M,S,MS : Word;
  765. begin
  766. DecodeTime(AValue,Result,M,S,MS);
  767. end;
  768. Function MinuteOfTheDay(const AValue: TDateTime): Word;
  769. Var
  770. H,M,S,MS : Word;
  771. begin
  772. DecodeTime(AValue,H,M,S,MS);
  773. Result:=(H*60)+M;
  774. end;
  775. Function SecondOfTheDay(const AValue: TDateTime): LongWord;
  776. Var
  777. H,M,S,MS : Word;
  778. begin
  779. DecodeTime(AValue,H,M,S,MS);
  780. Result:=((H*60)+M)*60+S;
  781. end;
  782. Function MilliSecondOfTheDay(const AValue: TDateTime): LongWord;
  783. Var
  784. H,M,S,MS : Word;
  785. begin
  786. DecodeTime(AValue,H,M,S,MS);
  787. Result:=(((H*60)+M)*60+S)*1000+MS;
  788. end;
  789. { ---------------------------------------------------------------------
  790. Part of hour functions.
  791. ---------------------------------------------------------------------}
  792. Function MinuteOfTheHour(const AValue: TDateTime): Word;
  793. Var
  794. H,S,MS : Word;
  795. begin
  796. DecodeTime(AValue,H,Result,S,MS);
  797. end;
  798. Function SecondOfTheHour(const AValue: TDateTime): Word;
  799. Var
  800. H,S,M,MS : Word;
  801. begin
  802. DecodeTime(AValue,H,M,S,MS);
  803. Result:=M*60+S;
  804. end;
  805. Function MilliSecondOfTheHour(const AValue: TDateTime): LongWord;
  806. Var
  807. H,S,M,MS : Word;
  808. begin
  809. DecodeTime(AValue,H,M,S,MS);
  810. Result:=(M*60+S)*1000+MS;
  811. end;
  812. { ---------------------------------------------------------------------
  813. Part of minute functions.
  814. ---------------------------------------------------------------------}
  815. Function SecondOfTheMinute(const AValue: TDateTime): Word;
  816. Var
  817. H,M,MS : Word;
  818. begin
  819. DecodeTime(AValue,H,M,Result,MS);
  820. end;
  821. Function MilliSecondOfTheMinute(const AValue: TDateTime): LongWord;
  822. Var
  823. H,S,M,MS : Word;
  824. begin
  825. DecodeTime(AValue,H,M,S,MS);
  826. Result:=S*1000+MS;
  827. end;
  828. { ---------------------------------------------------------------------
  829. Part of second functions.
  830. ---------------------------------------------------------------------}
  831. Function MilliSecondOfTheSecond(const AValue: TDateTime): Word;
  832. Var
  833. H,M,S : Word;
  834. begin
  835. DecodeTime(AValue,H,M,S,Result);
  836. end;
  837. { ---------------------------------------------------------------------
  838. Range checking functions.
  839. ---------------------------------------------------------------------}
  840. Function WithinPastYears(const ANow, AThen: TDateTime; const AYears: Integer): Boolean;
  841. begin
  842. Result:=YearsBetween(ANow,AThen)<=AYears;
  843. end;
  844. Function WithinPastMonths(const ANow, AThen: TDateTime; const AMonths: Integer): Boolean;
  845. begin
  846. Result:=MonthsBetween(ANow,AThen)<=AMonths;
  847. end;
  848. Function WithinPastWeeks(const ANow, AThen: TDateTime; const AWeeks: Integer): Boolean;
  849. begin
  850. Result:=WeeksBetween(ANow,AThen)<=AWeeks;
  851. end;
  852. Function WithinPastDays(const ANow, AThen: TDateTime; const ADays: Integer): Boolean;
  853. begin
  854. Result:=DaysBetween(ANow,AThen)<=ADays;
  855. end;
  856. Function WithinPastHours(const ANow, AThen: TDateTime; const AHours: Int64): Boolean;
  857. begin
  858. Result:=HoursBetween(ANow,AThen)<=AHours;
  859. end;
  860. Function WithinPastMinutes(const ANow, AThen: TDateTime; const AMinutes: Int64): Boolean;
  861. begin
  862. Result:=MinutesBetween(ANow,AThen)<=AMinutes;
  863. end;
  864. Function WithinPastSeconds(const ANow, AThen: TDateTime; const ASeconds: Int64): Boolean;
  865. begin
  866. Result:=SecondsBetween(ANow,Athen)<=ASeconds;
  867. end;
  868. Function WithinPastMilliSeconds(const ANow, AThen: TDateTime; const AMilliSeconds: Int64): Boolean;
  869. begin
  870. Result:=MilliSecondsBetween(ANow,AThen)<=AMilliSeconds;
  871. end;
  872. { ---------------------------------------------------------------------
  873. Period functions.
  874. ---------------------------------------------------------------------}
  875. {
  876. These functions are declared as approximate by Borland.
  877. A bit strange, since it can be calculated exactly ?
  878. }
  879. Function YearsBetween(const ANow, AThen: TDateTime): Integer;
  880. begin
  881. Result:=Trunc(Abs(ANow-AThen)/ApproxDaysPerYear);
  882. end;
  883. Function MonthsBetween(const ANow, AThen: TDateTime): Integer;
  884. begin
  885. Result:=Trunc(Abs(ANow-Athen)/ApproxDaysPerMonth);
  886. end;
  887. Function WeeksBetween(const ANow, AThen: TDateTime): Integer;
  888. begin
  889. Result:=Trunc(Abs(ANow-AThen)) div 7;
  890. end;
  891. Function DaysBetween(const ANow, AThen: TDateTime): Integer;
  892. begin
  893. Result:=Trunc(Abs(ANow-AThen));
  894. end;
  895. Function HoursBetween(const ANow, AThen: TDateTime): Int64;
  896. begin
  897. Result:=Trunc(Abs(ANow-AThen)*HoursPerDay);
  898. end;
  899. Function MinutesBetween(const ANow, AThen: TDateTime): Int64;
  900. begin
  901. Result:=Trunc(Abs(ANow-AThen)*MinsPerDay);
  902. end;
  903. Function SecondsBetween(const ANow, AThen: TDateTime): Int64;
  904. begin
  905. Result:=Trunc(Abs(ANow-AThen)*SecsPerDay);
  906. end;
  907. Function MilliSecondsBetween(const ANow, AThen: TDateTime): Int64;
  908. begin
  909. Result:=Trunc(Abs(ANow-AThen)*MSecsPerDay);
  910. end;
  911. { ---------------------------------------------------------------------
  912. Timespan in xxx functions.
  913. ---------------------------------------------------------------------}
  914. Function YearSpan(const ANow, AThen: TDateTime): Double;
  915. begin
  916. Result:=Abs(Anow-Athen)/ApproxDaysPerYear;
  917. end;
  918. Function MonthSpan(const ANow, AThen: TDateTime): Double;
  919. begin
  920. Result:=Abs(ANow-AThen)/ApproxDaysPerMonth;
  921. end;
  922. Function WeekSpan(const ANow, AThen: TDateTime): Double;
  923. begin
  924. Result:=Abs(ANow-AThen) / 7
  925. end;
  926. Function DaySpan(const ANow, AThen: TDateTime): Double;
  927. begin
  928. Result:=Abs(ANow-AThen);
  929. end;
  930. Function HourSpan(const ANow, AThen: TDateTime): Double;
  931. begin
  932. Result:=Abs(ANow-AThen)*HoursPerDay;
  933. end;
  934. Function MinuteSpan(const ANow, AThen: TDateTime): Double;
  935. begin
  936. Result:=Abs(ANow-AThen)*MinsPerDay;
  937. end;
  938. Function SecondSpan(const ANow, AThen: TDateTime): Double;
  939. begin
  940. Result:=Abs(ANow-AThen)*SecsPerDay;
  941. end;
  942. Function MilliSecondSpan(const ANow, AThen: TDateTime): Double;
  943. begin
  944. Result:=Abs(ANow-AThen)*MSecsPerDay;
  945. end;
  946. { ---------------------------------------------------------------------
  947. Increment/decrement functions.
  948. ---------------------------------------------------------------------}
  949. Function IncYear(const AValue: TDateTime; const ANumberOfYears: Integer ): TDateTime;
  950. Var
  951. Y,M,D,H,N,S,MS : Word;
  952. begin
  953. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  954. Y:=Y+ANumberOfYears;
  955. If (M=2) and (D=29) And (Not IsLeapYear(Y)) then
  956. D:=28;
  957. Result:=EncodeDateTime(Y,M,D,H,N,S,MS);
  958. end;
  959. Function IncYear(const AValue: TDateTime): TDateTime; // ; const ANumberOfYears: Integer = 1)
  960. begin
  961. Result:=IncYear(Avalue,1);
  962. end;
  963. Function IncWeek(const AValue: TDateTime; const ANumberOfWeeks: Integer): TDateTime;
  964. begin
  965. Result:=AValue+ANumberOfWeeks*7;
  966. end;
  967. Function IncWeek(const AValue: TDateTime): TDateTime; // ; const ANumberOfWeeks: Integer = 1)
  968. begin
  969. Result:=IncWeek(Avalue,1);
  970. end;
  971. Function IncDay(const AValue: TDateTime; const ANumberOfDays: Integer): TDateTime;
  972. begin
  973. Result:=AValue+ANumberOfDays;
  974. end;
  975. Function IncDay(const AValue: TDateTime): TDateTime; //; const ANumberOfDays: Integer = 1)
  976. begin
  977. Result:=IncDay(Avalue,1);
  978. end;
  979. Function IncHour(const AValue: TDateTime; const ANumberOfHours: Int64): TDateTime;
  980. begin
  981. Result:=AValue+ANumberOfHours/HoursPerDay;
  982. end;
  983. Function IncHour(const AValue: TDateTime): TDateTime; //; const ANumberOfHours: Int64 = 1
  984. begin
  985. Result:=IncHour(AValue,1);
  986. end;
  987. Function IncMinute(const AValue: TDateTime; const ANumberOfMinutes: Int64): TDateTime;
  988. begin
  989. Result:=Result+ANumberOfMinutes / MinsPerDay;
  990. end;
  991. Function IncMinute(const AValue: TDateTime): TDateTime; // ; const ANumberOfMinutes: Int64 = 1
  992. begin
  993. Result:=IncMinute(AValue,1);
  994. end;
  995. Function IncSecond(const AValue: TDateTime; const ANumberOfSeconds: Int64): TDateTime;
  996. begin
  997. Result:=AValue+ANumberOfSeconds / SecsPerDay;
  998. end;
  999. Function IncSecond(const AValue: TDateTime): TDateTime; // ; const ANumberOfSeconds: Int64 = 1
  1000. begin
  1001. Result:=IncSecond(Avalue,1);
  1002. end;
  1003. Function IncMilliSecond(const AValue: TDateTime; const ANumberOfMilliSeconds: Int64): TDateTime;
  1004. begin
  1005. Result:=AValue+ANumberOfMilliSeconds/MSecsPerDay;
  1006. end;
  1007. Function IncMilliSecond(const AValue: TDateTime): TDateTime; // ; const ANumberOfMilliSeconds: Int64 = 1
  1008. begin
  1009. Result:=IncMilliSecond(AValue,1);
  1010. end;
  1011. { ---------------------------------------------------------------------
  1012. Encode/Decode of complete timestamp
  1013. ---------------------------------------------------------------------}
  1014. Function EncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  1015. begin
  1016. If Not TryEncodeDateTime(AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond,Result) then
  1017. InvalidDateTimeError(AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond)
  1018. end;
  1019. Procedure DecodeDateTime(const AValue: TDateTime; var AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
  1020. begin
  1021. DecodeDate(AValue,AYear,AMonth,ADay);
  1022. DecodeTime(AValue,AHour,AMinute,ASecond,AMilliSecond);
  1023. end;
  1024. Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AValue: TDateTime): Boolean;
  1025. Var
  1026. tmp : TDateTime;
  1027. begin
  1028. Result:=TryEncodeDate(AYear,AMonth,ADay,AValue);
  1029. Result:=Result and TryEncodeTime(AHour,AMinute,ASecond,Amillisecond,Tmp);
  1030. If Result then
  1031. Avalue:=AValue+Tmp;
  1032. end;
  1033. { ---------------------------------------------------------------------
  1034. Encode/decode date, specifying week of year and day of week
  1035. ---------------------------------------------------------------------}
  1036. Function EncodeDateWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
  1037. begin
  1038. If Not TryEncodeDateWeek(AYear,AWeekOfYear,Result,ADayOfWeek) then
  1039. InvalidDateWeekError(AYear,AWeekOfYear,ADayOfWeek);
  1040. end;
  1041. Function EncodeDateWeek(const AYear, AWeekOfYear: Word): TDateTime; //; const ADayOfWeek: Word = 1
  1042. begin
  1043. Result := EncodeDateWeek(AYear,AWeekOfYear,1);
  1044. end;
  1045. Procedure DecodeDateWeek(const AValue: TDateTime; var AYear, AWeekOfYear, ADayOfWeek: Word);
  1046. var
  1047. DOY : Integer;
  1048. D: Word;
  1049. YS : TDateTime;
  1050. YSDOW, YEDOW: Word;
  1051. begin
  1052. AYear:=YearOf(AValue);
  1053. // Correct to ISO DOW
  1054. ADayOfWeek:=DayOfWeek(AValue)-1;
  1055. If ADAyOfWeek=0 then
  1056. ADayofweek:=7;
  1057. YS:=StartOfAYear(AYear);
  1058. DOY:=Trunc(AValue-YS)+1;
  1059. YSDOW:=DayOfTheWeek(YS);
  1060. // Correct week if later than wednesday. First week never starts later than wednesday
  1061. if (YSDOW<5) then
  1062. Inc(DOY,YSDOW-1)
  1063. else
  1064. Dec(DOY,8-YSDOW);
  1065. if (DOY<=0) then // Day is in last week of previous year.
  1066. DecodeDateWeek(YS-1,AYear,AWeekOfYear,D)
  1067. else
  1068. begin
  1069. AWeekOfYear:=DOY div 7;
  1070. if ((DOY mod 7)<>0) then
  1071. Inc(AWeekOfYear);
  1072. if (AWeekOfYear>52) then // Maybe in first week of next year ?
  1073. begin
  1074. YEDOW:=YSDOW;
  1075. if IsLeapYear(AYear) then
  1076. begin
  1077. Inc(YEDOW);
  1078. if (YEDOW>7) then
  1079. YEDOW:=1
  1080. else
  1081. end;
  1082. if (YEDOW<4) then // Really next year.
  1083. begin
  1084. Inc(AYear);
  1085. AWeekOfYear:=1;
  1086. end;
  1087. end;
  1088. end;
  1089. end;
  1090. Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime; const ADayOfWeek: Word): Boolean;
  1091. Var
  1092. DOW : Word;
  1093. Rest : Integer;
  1094. begin
  1095. Result:=IsValidDateWeek(Ayear,AWeekOfYear,ADayOfWeek);
  1096. If Result then
  1097. begin
  1098. AValue:=EncodeDate(AYear,1,1)+(7*(AWeekOfYear-1));
  1099. DOW:=DayOfTheWeek(AValue);
  1100. Rest:=ADayOfWeek-DOW;
  1101. If (DOW>4) then
  1102. Inc(Rest,7);
  1103. AValue:=AValue+Rest;
  1104. end;
  1105. end;
  1106. Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
  1107. begin
  1108. Result:=TryEncodeDateWeek(AYear,AWeekOfYear,AValue,1);
  1109. end;
  1110. { ---------------------------------------------------------------------
  1111. Encode/decode date, specifying day of year
  1112. ---------------------------------------------------------------------}
  1113. Function EncodeDateDay(const AYear, ADayOfYear: Word): TDateTime;
  1114. begin
  1115. If Not TryEncodeDateDay(AYear,ADayOfYear,Result) then
  1116. InvalidDateDayError(AYear,ADayOfYear);
  1117. end;
  1118. Procedure DecodeDateDay(const AValue: TDateTime; var AYear, ADayOfYear: Word);
  1119. Var
  1120. M,D : Word;
  1121. begin
  1122. DecodeDate(AValue,AYear,M,D);
  1123. ADayOfyear:=Trunc(AValue-EncodeDate(AYear,1,1))+1;
  1124. end;
  1125. Function TryEncodeDateDay(const AYear, ADayOfYear: Word; var AValue: TDateTime): Boolean;
  1126. begin
  1127. Result:=(ADayOfYear<>0) and (ADayOfYear<=DaysPerYear [IsleapYear(AYear)]);
  1128. If Result then
  1129. AValue:=EncodeDate(AYear,1,1)+ADayOfYear-1;
  1130. end;
  1131. { ---------------------------------------------------------------------
  1132. Encode/decode date, specifying week of month
  1133. ---------------------------------------------------------------------}
  1134. Function EncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word): TDateTime;
  1135. begin
  1136. If Not TryEncodeDateMonthWeek(Ayear,AMonth,AWeekOfMonth,ADayOfWeek,Result) then
  1137. InvalidDateMonthWeekError(AYear,AMonth,AWeekOfMonth,ADayOfWeek);
  1138. end;
  1139. Procedure DecodeDateMonthWeek(const AValue: TDateTime; var AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
  1140. Var
  1141. D,SDOM,EDOM : Word;
  1142. SOM,EOM : TdateTime;
  1143. DOM : Integer;
  1144. begin
  1145. DecodeDate(AValue,AYear,AMonth,D);
  1146. ADayOfWeek:=DayOfTheWeek(AValue);
  1147. SOM:=EncodeDate(Ayear,Amonth,1);
  1148. SDOM:=DayOfTheWeek(SOM);
  1149. DOM:=D-1+SDOM;
  1150. If SDOM>4 then
  1151. Dec(DOM,7);
  1152. // Too early in the month. First full week is next week, day is after thursday.
  1153. If DOM<=0 Then
  1154. DecodeDateMonthWeek(SOM-1,AYear,AMonth,AWeekOfMonth,D)
  1155. else
  1156. begin
  1157. AWeekOfMonth:=(DOM div 7)+Ord((DOM mod 7)<>0);
  1158. EDOM:=DayOfTheWeek(EndOfAMonth(Ayear,AMonth));
  1159. // In last days of last long week, so in next month...
  1160. If (EDOM<4) and ((DaysInAMonth(AYear,Amonth)-D)<EDOM) then
  1161. begin
  1162. AWeekOfMonth:=1;
  1163. Inc(AMonth);
  1164. If (AMonth=13) then
  1165. begin
  1166. AMonth:=1;
  1167. Inc(AYear);
  1168. end;
  1169. end;
  1170. end;
  1171. end;
  1172. Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
  1173. var
  1174. S : Word;
  1175. DOM : Integer;
  1176. begin
  1177. Result:=IsValidDateMonthWeek(AYear,AMonth,AWeekOfMonth,ADayOfWeek);
  1178. if Result then
  1179. begin
  1180. AValue:=EncodeDate(AYear,AMonth,1);
  1181. DOM:=(AWeekOfMonth-1)*7+ADayOfWeek-1;
  1182. { Correct for first week in last month.}
  1183. S:=DayOfTheWeek(AValue);
  1184. Dec(DOM,S-1);
  1185. if S in [DayFriday..DaySunday] then
  1186. Inc(DOM,7);
  1187. AValue:=AValue+DOM;
  1188. end;
  1189. end;
  1190. { ---------------------------------------------------------------------
  1191. Replace given element with supplied value.
  1192. ---------------------------------------------------------------------}
  1193. Const
  1194. LFAI = RecodeLeaveFieldAsIS; // Less typing, readable code
  1195. {
  1196. Note: We have little choice but to implement it like Borland did:
  1197. If AValue contains some 'wrong' value, it will throw an error.
  1198. To simulate this we'd have to check in each function whether
  1199. both arguments are correct. To avoid it, all is routed through
  1200. the 'central' RecodeDateTime function as in Borland's implementation.
  1201. }
  1202. Function RecodeYear(const AValue: TDateTime; const AYear: Word): TDateTime;
  1203. begin
  1204. Result := RecodeDateTime(AValue,AYear,LFAI,LFAI,LFAI,LFAI,LFAI,LFAI);
  1205. end;
  1206. Function RecodeMonth(const AValue: TDateTime; const AMonth: Word): TDateTime;
  1207. begin
  1208. Result := RecodeDateTime(AValue,LFAI,AMonth,LFAI,LFAI,LFAI,LFAI,LFAI);
  1209. end;
  1210. Function RecodeDay(const AValue: TDateTime; const ADay: Word): TDateTime;
  1211. begin
  1212. Result := RecodeDateTime(AValue,LFAI,LFAI,ADay,LFAI,LFAI,LFAI,LFAI);
  1213. end;
  1214. Function RecodeHour(const AValue: TDateTime; const AHour: Word): TDateTime;
  1215. begin
  1216. Result := RecodeDateTime(AValue,LFAI,LFAI,LFAI,AHour,LFAI,LFAI,LFAI);
  1217. end;
  1218. Function RecodeMinute(const AValue: TDateTime; const AMinute: Word): TDateTime;
  1219. begin
  1220. Result := RecodeDateTime(AValue,LFAI,LFAI,LFAI,LFAI,AMinute,LFAI,LFAI);
  1221. end;
  1222. Function RecodeSecond(const AValue: TDateTime; const ASecond: Word): TDateTime;
  1223. begin
  1224. Result := RecodeDateTime(AValue,LFAI,LFAI,LFAI,LFAI,LFAI,ASecond,LFAI);
  1225. end;
  1226. Function RecodeMilliSecond(const AValue: TDateTime; const AMilliSecond: Word): TDateTime;
  1227. begin
  1228. Result := RecodeDateTime(AValue,LFAI,LFAI,LFAI,LFAI,LFAI,LFAI,AMilliSecond);
  1229. end;
  1230. Function RecodeDate(const AValue: TDateTime; const AYear, AMonth, ADay: Word): TDateTime;
  1231. begin
  1232. Result := RecodeDateTime(AValue,AYear,AMonth,ADay,LFAI,LFAI,LFAI,LFAI);
  1233. end;
  1234. Function RecodeTime(const AValue: TDateTime; const AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  1235. begin
  1236. Result := RecodeDateTime(AValue,LFAI,LFAI,LFAI,AHour,AMinute,ASecond,AMilliSecond);
  1237. end;
  1238. Function RecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
  1239. begin
  1240. If Not TryRecodeDateTime(AValue,AYear,AMonth,ADay,AHour,AMinute,ASecond,AMilliSecond,Result) then
  1241. InvalidDateTimeError(AYear,AMonth,ADay,AHour,AMinute,ASecond,AMilliSecond,AValue);
  1242. end;
  1243. Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AResult: TDateTime): Boolean;
  1244. Procedure FV (Var AV : Word; Arg : Word);
  1245. begin
  1246. If (Arg<>LFAI) then
  1247. AV:=Arg;
  1248. end;
  1249. Var
  1250. Y,M,D,H,N,S,MS : Word;
  1251. begin
  1252. DecodeDateTime(AValue,Y,M,D,H,N,S,MS);
  1253. FV(Y,AYear);
  1254. FV(M,AMonth);
  1255. FV(D,ADay);
  1256. FV(H,AHour);
  1257. FV(N,AMinute);
  1258. FV(S,ASecond);
  1259. FV(MS,AMillisecond);
  1260. Result:=TryEncodeDateTime(Y,M,D,H,N,S,MS,AResult);
  1261. end;
  1262. { ---------------------------------------------------------------------
  1263. Comparision of date/time
  1264. ---------------------------------------------------------------------}
  1265. Function CompareDateTime(const A, B: TDateTime): TValueRelationship;
  1266. begin
  1267. If SameDateTime(A,B) then
  1268. Result:=EqualsValue
  1269. else If A>B then
  1270. Result:=GreaterThanValue
  1271. else
  1272. Result:=LessThanValue
  1273. end;
  1274. Function CompareDate(const A, B: TDateTime): TValueRelationship;
  1275. begin
  1276. If SameDate(A,B) then
  1277. Result:=EQualsValue
  1278. else if A<B then
  1279. Result:=LessThanValue
  1280. else
  1281. Result:=GreaterThanValue;
  1282. end;
  1283. Function CompareTime(const A, B: TDateTime): TValueRelationship;
  1284. begin
  1285. If SameTime(A,B) then
  1286. Result:=EQualsValue
  1287. else If Frac(A)<Frac(B) then
  1288. Result:=LessThanValue
  1289. else
  1290. Result:=GreaterThanValue;
  1291. end;
  1292. Function SameDateTime(const A, B: TDateTime): Boolean;
  1293. begin
  1294. Result:=Abs(A-B)<OneMilliSecond;
  1295. end;
  1296. Function SameDate(const A, B: TDateTime): Boolean;
  1297. begin
  1298. Result:=Trunc(A)=Trunc(B);
  1299. end;
  1300. Function SameTime(const A, B: TDateTime): Boolean;
  1301. begin
  1302. Result:=Frac(Abs(A-B))<OneMilliSecond;
  1303. end;
  1304. Function InternalNthDayOfWeek(DoM : Word) : Word;
  1305. begin
  1306. Result:=(Dom-1) div 7 +1;
  1307. end;
  1308. Function NthDayOfWeek(const AValue: TDateTime): Word;
  1309. begin
  1310. Result:=InternalNthDayOfWeek(DayOfTheMonth(AValue));
  1311. end;
  1312. Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; var AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
  1313. var
  1314. D: Word;
  1315. begin
  1316. DecodeDate(AValue,AYear,AMonth,D);
  1317. ADayOfWeek:=DayOfTheWeek(AValue);
  1318. ANthDayOfWeek:=InternalNthDayOfWeek(D);
  1319. end;
  1320. Function EncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word): TDateTime;
  1321. begin
  1322. If Not TryEncodeDayOfWeekInMonth(AYear,AMonth,ANthDayOfWeek,ADayOfWeek,Result) then
  1323. InvalidDayOfWeekInMonthError(AYear,AMonth,ANthDayOfWeek,ADayOfWeek);
  1324. end;
  1325. Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
  1326. Var
  1327. SOM,D : Word;
  1328. begin
  1329. SOM:=DayOfTheWeek(EncodeDate(Ayear,AMonth,1));
  1330. D:=1+ADayOfWeek-SOM+7*(ANthDayOfWeek-1);
  1331. If SOM>ADayOfWeek then
  1332. D:=D+7; // Clearer would have been Inc(ANthDayOfweek) but it's a const
  1333. Result:=TryEncodeDate(Ayear,AMonth,D,AValue);
  1334. end;
  1335. { ---------------------------------------------------------------------
  1336. Exception throwing routines
  1337. ---------------------------------------------------------------------}
  1338. Procedure InvalidDateTimeError(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; const ABaseDate: TDateTime);
  1339. Function DoField(Arg,Def : Word; Unknown: String) : String;
  1340. begin
  1341. If (Arg<>LFAI) then
  1342. Result:=Format('%.*d',[Length(Unknown),Arg])
  1343. else if (ABaseDate=0) then
  1344. Result:=Unknown
  1345. else
  1346. Result:=Format('%.*d',[Length(Unknown),Arg]);
  1347. end;
  1348. Var
  1349. Y,M,D,H,N,S,MS : Word;
  1350. Msg : String;
  1351. begin
  1352. DecodeDateTime(ABasedate,Y,M,D,H,N,S,MS);
  1353. Msg:=DoField(AYear,Y,'????');
  1354. Msg:=Msg+DateSeparator+DoField(AMonth,M,'??');
  1355. Msg:=Msg+DateSeparator+DoField(ADay,D,'??');
  1356. Msg:=Msg+' '+DoField(AHour,H,'??');
  1357. Msg:=Msg+TimeSeparator+DoField(AMinute,N,'??');
  1358. Msg:=Msg+TimeSeparator+Dofield(ASecond,S,'??');
  1359. Msg:=Msg+DecimalSeparator+DoField(AMilliSecond,MS,'???');
  1360. Raise EConvertError.CreateFmt(SErrInvalidTimeStamp,[Msg]);
  1361. end;
  1362. Procedure InvalidDateTimeError(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word); // const ABaseDate: TDateTime = 0
  1363. begin
  1364. InvalidDateTimeError(AYear,AMonth,ADay,AHour,AMinute,ASecond,AMilliSecond,0);
  1365. end;
  1366. Procedure InvalidDateWeekError(const AYear, AWeekOfYear, ADayOfWeek: Word);
  1367. begin
  1368. Raise EConvertError.CreateFmt(SErrInvalidDateWeek,[AYear,AWeekOfYear,ADayOfWeek]);
  1369. end;
  1370. Procedure InvalidDateDayError(const AYear, ADayOfYear: Word);
  1371. begin
  1372. Raise EConvertError.CreateFmt(SErrInvalidDayOfYear,[AYear,ADayOfYear]);
  1373. end;
  1374. Procedure InvalidDateMonthWeekError(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
  1375. begin
  1376. Raise EConvertError.CreateFmt(SErrInvalidDateMonthWeek,[Ayear,AMonth,AWeekOfMonth,ADayOfWeek]);
  1377. end;
  1378. Procedure InvalidDayOfWeekInMonthError(const AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
  1379. begin
  1380. Raise EConvertError.CreateFmt(SErrInvalidDayOfWeekInMonth,[AYear,AMonth,ANthDayOfWeek,ADayOfWeek]);
  1381. end;
  1382. { ---------------------------------------------------------------------
  1383. Julian and Modified Julian Date conversion support
  1384. ---------------------------------------------------------------------}
  1385. Function DateTimeToJulianDate(const AValue: TDateTime): Double;
  1386. begin
  1387. NotYetImplemented('DateTimeToJulianDate');
  1388. end;
  1389. Function JulianDateToDateTime(const AValue: Double): TDateTime;
  1390. begin
  1391. NotYetImplemented('JulianDateToDateTime');
  1392. end;
  1393. Function TryJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
  1394. begin
  1395. NotYetImplemented('TryJulianDateToDateTime');
  1396. end;
  1397. Function DateTimeToModifiedJulianDate(const AValue: TDateTime): Double;
  1398. begin
  1399. NotYetImplemented('DateTimeToModifiedJulianDate');
  1400. end;
  1401. Function ModifiedJulianDateToDateTime(const AValue: Double): TDateTime;
  1402. begin
  1403. NotYetImplemented('ModifiedJulianDateToDateTime');
  1404. end;
  1405. Function TryModifiedJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
  1406. begin
  1407. NotYetImplemented('TryModifiedJulianDateToDateTime');
  1408. end;
  1409. { ---------------------------------------------------------------------
  1410. Unix timestamp support.
  1411. ---------------------------------------------------------------------}
  1412. Function DateTimeToUnix(const AValue: TDateTime): Int64;
  1413. begin
  1414. NotYetImplemented('DateTimeToUnix');
  1415. end;
  1416. Function UnixToDateTime(const AValue: Int64): TDateTime;
  1417. begin
  1418. NotYetImplemented('UnixToDateTime');
  1419. end;
  1420. end.
  1421. {
  1422. $Log$
  1423. Revision 1.10 2004-12-30 13:06:53 michael
  1424. + Fixed DecodeDayOfWeekInMonth
  1425. Revision 1.9 2004/12/30 11:57:25 michael
  1426. + Fixed tryencodedatemonthweek, fixed recodedatetime milliseconds
  1427. Revision 1.8 2004/12/29 18:31:04 michael
  1428. * Fixed EndOfADay
  1429. Revision 1.7 2004/12/29 18:28:21 michael
  1430. * Fixed StartOfADay
  1431. Revision 1.6 2004/09/20 15:07:19 peter
  1432. * typo
  1433. Revision 1.5 2004/09/20 06:58:59 michael
  1434. + Fixed some errors pointed out by Armin Diehl
  1435. Revision 1.4 2004/09/19 19:25:52 armin
  1436. * fixed some compiler warnings
  1437. Revision 1.3 2004/08/12 12:26:34 michael
  1438. + Implemented decodedateweek
  1439. Revision 1.2 2004/01/10 19:35:17 michael
  1440. + Moved all resource strings to rtlconst/sysconst
  1441. Revision 1.1 2003/12/06 18:03:46 hajny
  1442. * include file for dateutil(s)
  1443. Revision 1.2 2003/01/19 14:37:06 michael
  1444. + Much more functions implemented
  1445. }