(* DateTime Utility Library Tuğrul HELVACI - 2010 www.tugrulhelvaci.com *) unit DateTimeUtils; interface uses Classes, SysUtils, DateUtils; type NewDateTime = record private fData : TDateTime; type TDateConverter = class private type TSeperator = record AlphaSection : String; NumSection : Integer; UseCurrentDate: Boolean; end; private class function ConvertTo(const AOldValue, AValue : String) : TDateTime; end; private function GetDateValues(const Index : Integer) : Word; procedure SetDateValues(const Index : Integer; const Value : Word); public constructor Create(const Source : TDateTime); overload; constructor Create(const Source : String); overload; function ToString : String; function ToDateTime : TDateTime; procedure SetDate(const SourceDate, DateFormat : String); function AddDay(const Value : Integer) : NewDateTime; function AddMonth(const Value : Integer) : NewDateTime; function AddYear(const Value : Integer) : NewDateTime; function AddHour(const Value : Integer) : NewDateTime; function AddMinute(const Value : Integer) : NewDateTime; function AddSecond(const Value : Integer) : NewDateTime; function AddMilliSecond(const Value : Integer) : NewDateTime; class operator Implicit(const Left : TDateTime) : NewDateTime; class operator Implicit(const Left : NewDateTime) : TDateTime; class operator Implicit(const Left : String) : NewDateTime; class operator Add(const Left : NewDateTime; const Right : Integer) : NewDateTime; class operator Add(const Left : Integer; const Right : NewDateTime) : NewDateTime; class operator Add(const Left : NewDateTime; const Right : String) : NewDateTime; class operator Add(const Left : String; const Right : NewDateTime) : NewDateTime; class operator Subtract(const Left : NewDateTime; const Right : Integer) : NewDateTime; class operator Subtract(const Left : Integer; const Right : NewDateTime) : NewDateTime; class operator Subtract(const Left : NewDateTime; const Right : String) : NewDateTime; class operator Subtract(const Left : String; const Right : NewDateTime) : NewDateTime; class operator Equal(const Left , Right : NewDateTime) : Boolean; class operator Equal(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator Equal(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator NotEqual(const Left , Right : NewDateTime) : Boolean; class operator NotEqual(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator NotEqual(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator GreaterThan(const Left, Right : NewDateTime) : Boolean; class operator GreaterThan(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator GreaterThan(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator GreaterThanOrEqual(const Left, Right : NewDateTime) : Boolean; class operator GreaterThanOrEqual(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator GreaterThanOrEqual(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator LessThan(const Left, Right : NewDateTime) : Boolean; class operator LessThan(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator LessThan(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator LessThanOrEqual(const Left, Right : NewDateTime) : Boolean; class operator LessThanOrEqual(const Left : NewDateTime; const Right : TDateTime) : Boolean; class operator LessThanOrEqual(const Left : TDateTime; const Right : NewDateTime) : Boolean; class operator Inc(const Left : NewDateTime) : NewDateTime; class operator Dec(const Left : NewDateTime) : NewDateTime; property Day : Word index 1 read GetDateValues write SetDateValues; property Month : Word index 2 read GetDateValues write SetDateValues; property Year : Word index 3 read GetDateValues write SetDateValues; property Hour : Word index 4 read GetDateValues write SetDateValues; property Minute : Word index 5 read GetDateValues write SetDateValues; property Second : Word index 6 read GetDateValues write SetDateValues; property MilliSecond : Word index 7 read GetDateValues write SetDateValues; end; implementation { NewDateTime } class operator NewDateTime.Add(const Left : NewDateTime; const Right : Integer): NewDateTime; begin Result := Left.AddDay(Right); end; class operator NewDateTime.Add(const Left: Integer; const Right: NewDateTime): NewDateTime; begin Result := Right.AddDay(Left); end; class operator NewDateTime.Add(const Left: NewDateTime; const Right: String): NewDateTime; begin Result.SetDate(Left.ToString, Right); end; class operator NewDateTime.Add(const Left: String; const Right: NewDateTime): NewDateTime; begin Result.SetDate(Right.ToString, Left); end; function NewDateTime.AddDay(const Value: Integer): NewDateTime; begin fData := IncDay(fData, Value); Result := Self; end; function NewDateTime.AddHour(const Value: Integer): NewDateTime; begin fData := IncHour(fData, Value); Result := Self; end; function NewDateTime.AddMilliSecond(const Value: Integer): NewDateTime; begin fData := IncMilliSecond(fData, Value); Result := Self; end; function NewDateTime.AddMinute(const Value: Integer): NewDateTime; begin fData := IncMinute(fData, Value); Result := Self; end; function NewDateTime.AddMonth(const Value: Integer): NewDateTime; begin fData := IncMonth(fData, Value); Result := Self; end; function NewDateTime.AddSecond(const Value: Integer): NewDateTime; begin fData := IncSecond(fData, Value); Result := Self; end; function NewDateTime.AddYear(const Value: Integer): NewDateTime; begin fData := IncYear(fData, Value); Result := Self; end; constructor NewDateTime.Create(const Source: String); begin fData := TDateConverter.ConvertTo('', Source); //ConvertToDateTime('', Source); end; class operator NewDateTime.Dec(const Left: NewDateTime): NewDateTime; begin Result := Left.AddDay(-1); end; class operator NewDateTime.Equal(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left = Right.fData; end; class operator NewDateTime.Equal(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData = Right; end; class operator NewDateTime.Equal(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData = Right.fData; end; constructor NewDateTime.Create(const Source: TDateTime); begin fData := Source; end; function NewDateTime.GetDateValues(const Index: Integer): Word; var fDay, fMonth, fYear, fHour, fMinute, fSecond, fMilliSecond : Word; begin DecodeDate(fData, fYear, fMonth, fDay); DecodeTime(fData, fHour, fMinute, fSecond, fMilliSecond); case Index of 1 : Result := fDay; 2 : Result := fMonth; 3 : Result := fYear; 4 : Result := fHour; 5 : Result := fMinute; 6 : Result := fSecond; 7 : Result := fMilliSecond; end; end; class operator NewDateTime.GreaterThan(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData > Right.fData; end; class operator NewDateTime.GreaterThan(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData > Right; end; class operator NewDateTime.GreaterThan(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left > Right.fData; end; class operator NewDateTime.GreaterThanOrEqual(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left >= Right.fData; end; class operator NewDateTime.GreaterThanOrEqual(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData >= Right; end; class operator NewDateTime.GreaterThanOrEqual(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData >= Right.fData; end; class operator NewDateTime.Implicit(const Left: String): NewDateTime; begin Result.SetDate('', Left); end; class operator NewDateTime.Inc(const Left: NewDateTime): NewDateTime; begin Result := Left.AddDay(1); end; class operator NewDateTime.LessThan(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left < Right.fData; end; class operator NewDateTime.LessThan(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData < Right; end; class operator NewDateTime.LessThan(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData < Right.fData; end; class operator NewDateTime.LessThanOrEqual(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData <= Right.fData; end; class operator NewDateTime.LessThanOrEqual(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData <= Right; end; class operator NewDateTime.LessThanOrEqual(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left <= Right.fData; end; class operator NewDateTime.NotEqual(const Left, Right: NewDateTime): Boolean; begin Result := Left.fData <> Right.fData; end; class operator NewDateTime.NotEqual(const Left: NewDateTime; const Right: TDateTime): Boolean; begin Result := Left.fData <> Right; end; class operator NewDateTime.NotEqual(const Left: TDateTime; const Right: NewDateTime): Boolean; begin Result := Left <> Right.fData; end; class operator NewDateTime.Implicit(const Left: NewDateTime): TDateTime; begin Result := Left.fData; end; class operator NewDateTime.Implicit(const Left: TDateTime): NewDateTime; begin Result.fData := Left; end; procedure NewDateTime.SetDate(const SourceDate, DateFormat: String); var dt : TDateTime; begin if Trim(SourceDate) <> '' then if TryStrToDateTime(SourceDate, dt) then begin fData := TDateConverter.ConvertTo(SourceDate, DateFormat); Exit; end else raise Exception.Create('Tarih formatında hata var.!'); fData := TDateConverter.ConvertTo(SourceDate, DateFormat); end; procedure NewDateTime.SetDateValues(const Index: Integer; const Value: Word); var fDay, fMonth, fYear, fHour, fMinute, fSecond, fMilliSecond : Word; begin DecodeDate(fData, fYear, fMonth, fDay); DecodeTime(fData, fHour, fMinute, fSecond, fMilliSecond); case Index of 1 : fDay := Value; 2 : fMonth := Value; 3 : fYear := Value; 4 : fHour := Value; 5 : fMinute := Value; 6 : fSecond := Value; 7 : fMilliSecond := Value; end; if not TryEncodeDateTime(fYear, fMonth, fDay, fHour, fMinute, fSecond, fMilliSecond, fData) then raise Exception.Create('Tarih/Saat atamasında hata oluştu.!'); end; class operator NewDateTime.Subtract(const Left: Integer; const Right: NewDateTime): NewDateTime; begin Result := Right.AddDay(-Left); end; class operator NewDateTime.Subtract(const Left: NewDateTime; const Right: Integer): NewDateTime; begin Result := Left.AddDay(-Right); end; function NewDateTime.ToDateTime: TDateTime; begin Result := fData; end; function NewDateTime.ToString: String; begin Result := DateTimeToStr(fData); end; class operator NewDateTime.Subtract(const Left: NewDateTime; const Right: String): NewDateTime; begin Result.SetDate('', Right); end; class operator NewDateTime.Subtract(const Left: String; const Right: NewDateTime): NewDateTime; begin Result.SetDate('', Left); end; { NewDateTime.TDateConverter } class function NewDateTime.TDateConverter.ConvertTo(const AOldValue, AValue: String): TDateTime; function Parse(const Value : String) : TSeperator; var iCounter : Integer; sNum, sValue : String; TAlpha : set of Char; //'a'..'z'; TNums : set of Char; //'0'..'9'; begin sNum := ''; sValue := LowerCase(Value); TAlpha := ['a'..'z']; TNums := ['0'..'9']; Result.AlphaSection := ''; Result.NumSection := 0; Result.UseCurrentDate := false; for iCounter := 1 to Length(sValue) do begin if sValue[iCounter] in TAlpha then Result.AlphaSection := Result.AlphaSection + sValue[iCounter]; if sValue[iCounter] in TNums then sNum := sNum + sValue[iCounter]; if sValue[iCounter] = '*' then Result.UseCurrentDate := true; end; if sNum <> '' then Result.NumSection := StrToIntDef(sNum, 0); end; function IfThen(const Expression : Boolean; const TrueDate, FalseDate : TDateTime) : TDateTime; begin if Expression then Result := TrueDate else Result := FalseDate; end; var sVal, sTmp, Value : String; iIndex, iMultiplier : Integer; OldDate : TDateTime; Separator : TSeperator; sList : TStrings; begin Result := 0; iMultiplier := 1; OldDate := Now; if Trim(AOldValue) <> '' then OldDate := StrToDateTimeDef(Trim(AOldValue), Now); sVal := Trim(AValue); sVal := StringReplace(sVal, 'Ü', 'ü', [rfReplaceAll]); sVal := StringReplace(sVal, 'Ş', 'ş', [rfReplaceAll]); sVal := StringReplace(sVal, 'İ', 'i', [rfReplaceAll]); sVal := LowerCase(sVal); sVal := StringReplace(sVal, '.', DateSeparator, [rfReplaceAll]); sVal := StringReplace(sVal, ',', DateSeparator, [rfReplaceAll]); sVal := StringReplace(sVal, '/', DateSeparator, [rfReplaceAll]); if Pos(DateSeparator, sVal) <> 0 then begin try Result := StrToDate(sVal); Exit; except end; end; if Length(sVal) = 0 then Exit; if (sVal = 'bugün') or (sVal = 'bugun') or (sVal = 'şimdi') or (sVal = 'simdi') or (sVal = 'today') or (sVal = 'now') then Exit(Now); if (sVal = 'yarın') or (sVal = 'yarin') or (sVal = 'tomorrow') then Exit(Now + 1); if (sVal = 'dün') or (sVal = 'dun') or (sVal = 'yesterday') then Exit(Now - 1); sList := TStringList.Create; ExtractStrings([';', ' '], [], PWideChar(sVal), sList); iIndex := -1; for Value in sList do begin Inc(iIndex); sTmp := Trim(Value); if not (sTmp[1] in ['-', '+']) then Insert('+', sTmp, 1); // + yada - işareti belirtilmemişse + kabul et. if sTmp[1] = '-' then iMultiplier := -1 else iMultiplier := 1; if (sTmp[1] in ['-', '+']) and (Length(sTmp) >= 3) then begin Delete(sTmp, 1, 1); // -, + Separator := Parse(sTmp); if Separator.AlphaSection = '' then Separator.AlphaSection := 'g'; if Separator.AlphaSection = 'g' then // Gün begin if Separator.UseCurrentDate then Result := IncDay(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncDay(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; if Separator.AlphaSection = 'a' then // Ay begin if Separator.UseCurrentDate then Result := IncMonth(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncMonth(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; if Separator.AlphaSection = 'y' then // Yıl begin if Separator.UseCurrentDate then Result := IncYear(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncYear(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; if Separator.AlphaSection = 's' then // Saat begin if Separator.UseCurrentDate then Result := IncHour(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncHour(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; if Separator.AlphaSection = 'dk' then // Dakika begin if Separator.UseCurrentDate then Result := IncMinute(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncMinute(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; if Separator.AlphaSection = 'sn' then // Saniye begin if Separator.UseCurrentDate then Result := IncSecond(IfThen(Result = 0, Now , Result), iMultiplier * Separator.NumSection) else Result := IncSecond(IfThen(Result = 0, OldDate, Result), iMultiplier * Separator.NumSection); end; end; // if iIndex = sList.Count - 1 then Exit; end; if (Length(sVal) mod 2) <> 0 then sVal := '0' + sVal; if ( Length(sVal) = 6 ) or ( Length(sVal) = 8 ) then // 10031975 , 100375 gibi tarih girişleri begin Insert( DateSeparator, sVal, 5 ); Insert( DateSeparator, sVal, 3 ); TryStrToDate(sVal, Result); Exit; end; // raise Exception.Create('Tarih/Saat dönüşümlerinde hata.!'); end; end.