Skip to content

Commit 9d391cb

Browse files
author
delphidabbler
committed
Added new TryParseSQLDateTime routine
Rewrote ParseSQLDateTime in terms of TryParseSQLDateTime Tweaked some XMLDoc comments.
1 parent 2b71593 commit 9d391cb

File tree

1 file changed

+53
-20
lines changed

1 file changed

+53
-20
lines changed

Src/UUtils.pas

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,21 @@ function NowGMT: TDateTime;
8989

9090
/// <summary>Converts a date-time value in SQL format into a TDateTime.
9191
/// </summary>
92-
/// <param name="SQLDate">string [in] SQL format date-time value to be
92+
/// <param name="SQLDateTime">string [in] SQL format date-time value to be
9393
/// converted.</param>
9494
/// <returns>TDateTime. Converted value.</returns>
9595
/// <remarks>SQLDate must be in YYYY-MM-DD hh:mm:ss format.</remarks>
96-
function ParseSQLDateTime(const SQLDate: string): TDateTime;
96+
function ParseSQLDateTime(const SQLDateTime: string): TDateTime;
97+
98+
/// <summary>Attempts to convert a date-time value in SQL format into a
99+
/// TDateTime value.</summary>
100+
/// <param name="SQLDateTime">string [in] SQL format date-time value to be
101+
/// converted.</param>
102+
/// <param name="Value">TDateTime [out] Set to converted date-time value if
103+
/// conversion succeeded or undefined if coversion failed.</param>
104+
/// <returns>Boolean. True if conversion succeeded, False otherwise.</returns>
105+
function TryParseSQLDateTime(const SQLDateTime: string; out Value: TDateTime):
106+
Boolean;
97107

98108
/// <summary>Get a desired interface pointer to an object instance.</summary>
99109
/// <param name="Instance">IInterface [in] Instance for which an interface is
@@ -165,10 +175,11 @@ function IsEqualBytes(const BA1, BA2: TBytes; const Count: Cardinal):
165175
/// <remarks>If both arrays are empty they are considered equal.</remarks>
166176
function IsEqualBytes(const BA1, BA2: TBytes): Boolean; overload;
167177

168-
/// <summary>Attempts to convert a string to a Word value.</summary>
169-
/// <param name="S">string [in] String to convert.</param>
170-
/// <param name="W">Word [out] Converted value.</param>
171-
/// <returns>Boolean. True if conversion succeeded, False otherwise.</returns>
178+
/// <summary>Attempts to convert string S into a Word value.</summary>
179+
/// <param name="S">string [in] String to be converted.</param>
180+
/// <param name="W">Cardinal [out] Value of converted string. Undefined if
181+
/// conversion fails.</param>
182+
/// <returns>Boolean. True if conversion succeeds, False if not.</returns>
172183
/// <remarks>String must represent a non-negative integer that is representable
173184
/// as a Word.</remarks>
174185
function TryStrToWord(const S: string; out W: Word): Boolean;
@@ -179,7 +190,7 @@ implementation
179190

180191
uses
181192
// Delphi
182-
Windows, ShlObj, ActiveX, Messages, Character, Math,
193+
Windows, ShlObj, ActiveX, Messages, Character, Math, DateUtils,
183194
// Project
184195
UConsts, UStrUtils;
185196

@@ -318,20 +329,32 @@ function RFC1123DateStamp: string;
318329
Result := FormatDateTime(cRFC1123Pattern, NowGMT);
319330
end;
320331

321-
function ParseSQLDateTime(const SQLDate: string): TDateTime;
332+
function ParseSQLDateTime(const SQLDateTime: string): TDateTime;
333+
resourcestring
334+
sBadDate = '"%s" is not a valid SQL DateTime';
335+
begin
336+
if not TryParseSQLDateTime(SQLDateTime, Result) then
337+
raise EConvertError.CreateFmt(sBadDate, [SQLDateTime]);
338+
end;
339+
340+
function TryParseSQLDateTime(const SQLDateStr: string; out Value: TDateTime):
341+
Boolean;
342+
var
343+
Year, Month, Day, Hour, Min, Sec: Word;
322344
begin
323-
Result := SysUtils.EncodeDate(
324-
SysUtils.StrToInt(Copy(SQLDate, 1, 4)),
325-
SysUtils.StrToInt(Copy(SQLDate, 6, 2)),
326-
SysUtils.StrToInt(Copy(SQLDate, 9, 2))
327-
)
328-
+
329-
SysUtils.EncodeTime(
330-
SysUtils.StrToInt(Copy(SQLDate, 12, 2)),
331-
SysUtils.StrToInt(Copy(SQLDate, 15, 2)),
332-
SysUtils.StrToInt(Copy(SQLDate, 18, 2)),
333-
0
334-
);
345+
if not TryStrToWord(Copy(SQLDateTime, 1, 4), Year) then
346+
Exit(False);
347+
if not TryStrToWord(Copy(SQLDateTime, 6, 2), Month) then
348+
Exit(False);
349+
if not TryStrToWord(Copy(SQLDateTime, 9, 2), Day) then
350+
Exit(False);
351+
if not TryStrToWord(Copy(SQLDateTime, 12, 2), Hour) then
352+
Exit(False);
353+
if not TryStrToWord(Copy(SQLDateTime, 15, 2), Min) then
354+
Exit(False);
355+
if not TryStrToWord(Copy(SQLDateTime, 18, 2), Sec) then
356+
Exit(False);
357+
Result := TryEncodeDateTime(Year, Month, Day, Hour, Min, Sec, 0, Value);
335358
end;
336359

337360
procedure GetIntf(const Instance: IInterface; const IID: TGUID; out Intf);
@@ -415,6 +438,16 @@ function TryStrToCardinal(const S: string; out Value: Cardinal): Boolean;
415438
Value := Int64Rec(Value64).Lo;
416439
end;
417440

441+
function TryStrToWord(const S: string; out Value: Word): Boolean;
442+
var
443+
ValueInt: Integer;
444+
begin
445+
Result := TryStrToInt(S, ValueInt)
446+
and (LongRec(ValueInt).Hi = 0);
447+
if Result then
448+
Value := LongRec(ValueInt).Lo;
449+
end;
450+
418451
function IsEqualBytes(const BA1, BA2: TBytes; const Count: Cardinal):
419452
Boolean;
420453
var

0 commit comments

Comments
 (0)