tvplanit: Some refactoring of several date/time routines.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5171 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-09-17 15:48:39 +00:00
parent b7aa833a11
commit 824cbb6a59
5 changed files with 122 additions and 87 deletions

View File

@ -352,6 +352,9 @@ type
implementation implementation
uses uses
{$IFDEF LCL}
DateUtils,
{$ENDIF}
VpCalendarPainter; VpCalendarPainter;
const const
@ -479,8 +482,8 @@ begin
Inc(Y); Inc(Y);
M := M + MO; M := M + MO;
{set day} {set day}
if D > DaysInMonth(Y, MO) then if D > DaysInAMonth(Y, MO) then
D := DaysInMonth(Y, MO); D := DaysInAMonth(Y, MO);
SetDate(calGetValidDate(EncodeDate(Y, MO, D)-1, +1)); SetDate(calGetValidDate(EncodeDate(Y, MO, D)-1, +1));
if (Assigned(FOnChange)) then if (Assigned(FOnChange)) then
FOnChange(Self, FDate); FOnChange(Self, FDate);
@ -556,13 +559,13 @@ begin
clFirst := I; clFirst := I;
{find the index of the last day in the month} {find the index of the last day in the month}
clLast := clFirst + DaysInMonth(clYear, clMonth) - 1; clLast := clFirst + DaysInAMonth(clYear, clMonth) - 1;
{initialize the first part of the calendar} {initialize the first part of the calendar}
if clMonth = 1 then if clMonth = 1 then
J := DaysInMonth(clYear - 1, 12) J := DaysInAMonth(clYear - 1, 12)
else else
J := DaysInMonth(clYear, clMonth-1); J := DaysInAMonth(clYear, clMonth-1);
for I := clFirst-1 downto 1 do begin for I := clFirst-1 downto 1 do begin
clCalendar[I] := J; clCalendar[I] := J;
Dec(J); Dec(J);
@ -1046,10 +1049,10 @@ begin
VK_END: VK_END:
if ssCtrl in Shift then begin if ssCtrl in Shift then begin
DecodeDate(FDate, Y, M, D); DecodeDate(FDate, Y, M, D);
SetDate(calGetValidDate(EncodeDate(Y, 12, DaysInMonth(Y, 12))+1, -1)); SetDate(calGetValidDate(EncodeDate(Y, 12, DaysInAMonth(Y, 12))+1, -1));
end else if Shift = [] then begin end else if Shift = [] then begin
DecodeDate(FDate, Y, M, D); DecodeDate(FDate, Y, M, D);
SetDate(calGetValidDate(EncodeDate(Y, M, DaysInMonth(Y, M))+1, -1)); SetDate(calGetValidDate(EncodeDate(Y, M, DaysInAMonth(Y, M))+1, -1));
end; end;
VK_PRIOR: VK_PRIOR:
@ -1363,8 +1366,8 @@ begin
iM := iM + 12; iM := iM + 12;
Dec(iY); Dec(iY);
end; end;
if iD > DaysInMonth(iY, iM) then if iD > DaysInAMonth(iY, iM) then
iD := DaysInMonth(iY, iM); iD := DaysInAMonth(iY, iM);
SetDate(calGetValidDate(EncodeDate(iY, iM, iD)-1, +1)); SetDate(calGetValidDate(EncodeDate(iY, iM, iD)-1, +1));
end; end;
@ -1378,8 +1381,8 @@ begin
DecodeDate(FDate, Y, M, D); DecodeDate(FDate, Y, M, D);
iY := Y; iM := M; iD := D; iY := Y; iM := M; iD := D;
Inc(iY, Delta); Inc(iY, Delta);
if iD > DaysInMonth(iY, iM) then if iD > DaysInAMonth(iY, iM) then
iD := DaysInMonth(iY, iM); iD := DaysInAMonth(iY, iM);
SetDate(calGetValidDate(EncodeDate(iY, iM, iD)-1, +1)); SetDate(calGetValidDate(EncodeDate(iY, iM, iD)-1, +1));
end; end;
{=====} {=====}

View File

@ -491,6 +491,9 @@ type
implementation implementation
uses uses
{$IFDEF LCL}
DateUtils,
{$ENDIF}
SysUtils, StrUtils, Math, Dialogs, SysUtils, StrUtils, Math, Dialogs,
VpEvntEditDlg, VpDayViewPainter; VpEvntEditDlg, VpDayViewPainter;
@ -1310,8 +1313,8 @@ begin
Y := Y + 1; Y := Y + 1;
end else end else
M := M + 1; M := M + 1;
if (D > DaysInMonth(Y, M)) then if (D > DaysInAMonth(Y, M)) then
D := DaysInMonth(Y, M); D := DaysInAMonth(Y, M);
Date := EncodeDate(Y, M, D); Date := EncodeDate(Y, M, D);
end; end;
@ -1327,8 +1330,8 @@ begin
Y := Y - 1; Y := Y - 1;
end else end else
M := M - 1; M := M - 1;
if (D > DaysInMonth(Y, M)) then if (D > DaysInAMonth(Y, M)) then
D := DaysInMonth(Y, M); D := DaysInAMonth(Y, M);
Date := EncodeDate(Y, M, D); Date := EncodeDate(Y, M, D);
end; end;

View File

@ -59,21 +59,22 @@ const
GranularityMinutes: Array[TVpGranularity] of Integer = (5, 6, 10, 15, 20, 30, 60); GranularityMinutes: Array[TVpGranularity] of Integer = (5, 6, 10, 15, 20, 30, 60);
function DaysInMonth(Year, Month : Integer) : Integer;
{-return the number of days in the specified month of a given year}
function DefaultEpoch : Integer; function DefaultEpoch : Integer;
{-return the current century} {-return the current century}
//function GetLeftButton : Byte; //function GetLeftButton : Byte;
procedure GetRGB(Clr : TColor; var IR, IG, IB : Byte); procedure GetRGB(Clr : TColor; var IR, IG, IB : Byte);
function IsLeapYear(Year : Integer) : Boolean;
function GetStartOfWeek(Date: TDateTime; StartOn: TVpDayType): TDateTime; function GetStartOfWeek(Date: TDateTime; StartOn: TVpDayType): TDateTime;
procedure StripString(var Str: string); procedure StripString(var Str: string);
{ strips non-alphanumeric characters from the beginning and end of the string} { strips non-alphanumeric characters from the beginning and end of the string}
function AssembleName(Contact: TVpContact): string; function AssembleName(Contact: TVpContact): string;
{ returns an assembled name string } { returns an assembled name string }
procedure ParseName(Contact: TVpContact; const Value: string); procedure ParseName(Contact: TVpContact; const Value: string);
{ parses the name into it's elements and updates the contact } { parses the name into it's elements and updates the contact }
procedure ParseCSZ(Str: string; var City, State, Zip: string); procedure ParseCSZ(Str: string; var City, State, Zip: string);
{ parses the string and returns the city, state and zip parameters } { parses the string and returns the city, state and zip parameters }
@ -85,34 +86,44 @@ function LoadBaseCursor(lpCursorName : PAnsiChar) : HCURSOR;
{$ENDIF} {$ENDIF}
function HeightOf(const R : TRect) : Integer; function HeightOf(const R : TRect) : Integer;
{- return the height of the TRect} {- returns the height of the TRect}
function WidthOf(const R : TRect) : Integer; function WidthOf(const R : TRect) : Integer;
{- return the width of the TRect} {- returns the width of the TRect}
function RightOf(AControl: TControl): Integer; function RightOf(AControl: TControl): Integer;
{- returns the right edge of a control } {- returns the right edge of a control }
function BottomOf(AControl: TControl): Integer; function BottomOf(AControl: TControl): Integer;
{- returns the bottom edge of a control } {- returns the bottom edge of a control }
function GetDisplayString(Canvas : TCanvas; const S : string; function GetDisplayString(Canvas : TCanvas; const S : string;
MinChars, MaxWidth : Integer) : string; MinChars, MaxWidth : Integer) : string;
{-given a string, a minimum number of chars to display, and a max width, } { given a string, a minimum number of chars to display, and a max width,
{ find the string that can be displayed in that width - add ellipsis to } find the string that can be displayed in that width - add ellipsis to
{ the end if necessary and possible } the end if necessary and possible }
procedure DrawBevelRect(const Canvas: TCanvas; R: TRect; procedure DrawBevelRect(const Canvas: TCanvas; R: TRect;
Shadow, Highlight: TColor); Shadow, Highlight: TColor);
{-draws a bevel in the specified TRect, using the specified colors } { Draws a bevel in the specified TRect, using the specified colors }
function PointInRect(Point: TPoint; Rect: TRect): Boolean; function PointInRect(Point: TPoint; Rect: TRect): Boolean;
{-determines if the specified point resides inside the specified TRect } { Determines if the specified point resides inside the specified TRect }
function GetAlarmAdvanceTime(Advance: Integer; AdvanceType: TVpAlarmAdvType): TDateTime; function GetAlarmAdvanceTime(Advance: Integer; AdvanceType: TVpAlarmAdvType): TDateTime;
{$IFDEF DELPHI}{$IFNDEF Delphi6} {$IFDEF DELPHI}{$IFNDEF Delphi6}
function IsLeapYear(Year: Integer): Boolean;
function MonthOfTheYear(TheDate: TDateTime): Word; function MonthOfTheYear(TheDate: TDateTime): Word;
procedure IncAMonth(var Year, Month, Day: Word; NumMonths: Integer); procedure IncAMonth(var Year, Month, Day: Word; NumMonths: Integer);
function IncMonth(const TheDate: TDateTime; NumberOfMonths: Integer): TDateTime; function IncMonth(const TheDate: TDateTime; NumberOfMonths: Integer): TDateTime;
function IncYear(TheDate: TDateTime; NumYears: Integer): TDateTime; function IncYear(TheDate: TDateTime; NumYears: Integer): TDateTime;
function TimeOf(ADateTime: TDateTime): TDateTime; function TimeOf(ADateTime: TDateTime): TDateTime;
function DateOf(ADateTime: TDateTime): TDateTime; function DateOf(ADateTime: TDateTime): TDateTime;
function DaysInAMonth(Year, Month: Integer): Integer;
{-return the number of days in the specified month of a given year}
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
function GetJulianDate(Date: TDateTime): Word; function GetJulianDate(Date: TDateTime): Word;
@ -124,7 +135,6 @@ function TimeInRange(ATime, StartTime, EndTime: TDateTime; IncludeLimits: Boolea
function GetTimeFormat: TVpTimeFormat; function GetTimeFormat: TVpTimeFormat;
function GetTimeFormatStr(ATimeFormat: TVpTimeFormat): String; function GetTimeFormatStr(ATimeFormat: TVpTimeFormat): String;
function GranularityToStr(Gran: TVpGranularity): string;
function HourToAMPM(Hour: TVpHours): string; function HourToAMPM(Hour: TVpHours): string;
function HourToStr(Hour: TVpHours; Mil: Boolean): string; function HourToStr(Hour: TVpHours; Mil: Boolean): string;
@ -134,6 +144,8 @@ function GetEndLine(EndTime: TDateTime; Granularity: TVpGranularity): Integer;
function LineToStartTime(Line: Integer; Granularity: TVpGranularity): TDateTime; function LineToStartTime(Line: Integer; Granularity: TVpGranularity): TDateTime;
function GetLineDuration(Granularity: TVpGranularity): Double; function GetLineDuration(Granularity: TVpGranularity): Double;
function GranularityToStr(Gran: TVpGranularity): string;
function TaskPriorityToStr(APriority: TVpTaskPriority): String; function TaskPriorityToStr(APriority: TVpTaskPriority): String;
function AutoHeight(ARadioGroup: TRadioGroup): Integer; function AutoHeight(ARadioGroup: TRadioGroup): Integer;
@ -287,12 +299,14 @@ end;
function GetDisplayString(Canvas : TCanvas; const S : string; function GetDisplayString(Canvas : TCanvas; const S : string;
MinChars, MaxWidth : Integer) : string; MinChars, MaxWidth : Integer) : string;
const
ELLIPSIS = '...';
var var
iDots, EllipsisWidth, Extent, Len, Width : Integer; iDots, EllipsisWidth, Extent, Len, Width : Integer;
ShowEllipsis : Boolean; ShowEllipsis : Boolean;
begin begin
{be sure that the Canvas Font is set before entering this routine} {be sure that the Canvas Font is set before entering this routine}
EllipsisWidth := Canvas.TextWidth('...'); EllipsisWidth := Canvas.TextWidth(ELLIPSIS);
Len := Length(S); Len := Length(S);
Result := S; Result := S;
Extent := Canvas.TextWidth(Result); Extent := Canvas.TextWidth(Result);
@ -309,7 +323,7 @@ begin
Extent := Canvas.TextWidth(Result); Extent := Canvas.TextWidth(Result);
end; end;
if ShowEllipsis then begin if ShowEllipsis then begin
Result := Result + '...'; Result := Result + ELLIPSIS;
inc(Len, 3); inc(Len, 3);
Extent := Canvas.TextWidth(Result); Extent := Canvas.TextWidth(Result);
iDots := 3; iDots := 3;
@ -345,20 +359,6 @@ begin
end; end;
{=====} {=====}
function DaysInMonth(Year, Month : Integer) : Integer;
begin
if (Year < 100) then
raise EVpDateException.Create(RSInvalidYear + ' "' + IntToStr(Year) + '"');
case Month of
1, 3, 5, 7, 8, 10, 12 : Result := 31;
4, 6, 9, 11 : Result := 30;
2 : Result := 28+Ord(IsLeapYear(Year));
else
Result := 0;
end;
end;
{=====}
function DefaultEpoch : Integer; function DefaultEpoch : Integer;
var var
ThisYear : Word; ThisYear : Word;
@ -386,13 +386,6 @@ begin
end; end;
{=====} {=====}
function IsLeapYear(Year : Integer) : Boolean;
begin
Result := (Year mod 4 = 0) and (Year mod 4000 <> 0) and
((Year mod 100 <> 0) or (Year mod 400 = 0));
end;
{=====}
function GetStartOfWeek(Date: TDateTime; StartOn: TVpDayType): TDateTime; function GetStartOfWeek(Date: TDateTime; StartOn: TVpDayType): TDateTime;
begin begin
result := Date; result := Date;
@ -410,13 +403,18 @@ end;
{$IFDEF DELPHI} {$IFNDEF Delphi6} {$IFDEF DELPHI} {$IFNDEF Delphi6}
function IsLeapYear(Year: Integer): Boolean;
begin
Result := (Year mod 4 = 0) and (Year mod 4000 <> 0) and
((Year mod 100 <> 0) or (Year mod 400 = 0));
end;
function MonthOfTheYear(TheDate: TDateTime): Word; function MonthOfTheYear(TheDate: TDateTime): Word;
var var
Year, Day: Word; Year, Day: Word;
begin begin
DecodeDate(TheDate, Year, Result, Day); DecodeDate(TheDate, Year, Result, Day);
end; end;
{=====}
procedure IncAMonth(var Year, Month, Day: Word; NumMonths: Integer); procedure IncAMonth(var Year, Month, Day: Word; NumMonths: Integer);
type type
@ -446,7 +444,6 @@ begin
if Day > DayTable^[Month] then if Day > DayTable^[Month] then
Day := DayTable^[Month]; Day := DayTable^[Month];
end; end;
{=====}
function IncMonth(const TheDate: TDateTime; NumberOfMonths: Integer): TDateTime; function IncMonth(const TheDate: TDateTime; NumberOfMonths: Integer): TDateTime;
var var
@ -456,9 +453,8 @@ begin
IncAMonth(Year, Month, Day, NumberOfMonths); IncAMonth(Year, Month, Day, NumberOfMonths);
Result := EncodeDate(Year, Month, Day); Result := EncodeDate(Year, Month, Day);
end; end;
{=====}
function IncYea (TheDate: TDateTime; NumYear : Integer) : TDateTime; function IncYear(TheDate: TDateTime; NumYear : Integer) : TDateTime;
begin begin
Result := IncMont (TheDate, NumYears * 12); Result := IncMont (TheDate, NumYears * 12);
end; end;
@ -473,7 +469,18 @@ begin
Result := frac(ADateTime); Result := frac(ADateTime);
end; end;
{=====} function DaysInAMonth(Year, Month: Integer): Integer;
begin
if (Year < 100) then
raise EVpDateException.Create(RSInvalidYear + ' "' + IntToStr(Year) + '"');
case Month of
1, 3, 5, 7, 8, 10, 12 : Result := 31;
4, 6, 9, 11 : Result := 30;
2 : Result := 28 + Ord(IsLeapYear(Year));
else
Result := 0;
end;
end;
{$ENDIF}{$ENDIF} {$ENDIF}{$ENDIF}
function GetJulianDate(Date: TDateTime): Word; function GetJulianDate(Date: TDateTime): Word;
@ -486,7 +493,7 @@ begin
{ Inc Julian by the number of days in each of the elapsed months } { Inc Julian by the number of days in each of the elapsed months }
for I := 1 to M do for I := 1 to M do
Inc(Julian, DaysInMonth(Y, I)); Inc(Julian, DaysInAMonth(Y, I));
{ add in the elapsed days from this month } { add in the elapsed days from this month }
Julian := Julian + D; Julian := Julian + D;
@ -582,6 +589,10 @@ begin
end; end;
{=====} {=====}
{ Checks whether the given date value is within the specified date interval
between StartDate and EndDate. If IncludeLimits is true then the function
result is true also if the date is equal to the date parts of the StartDate
or EndDate. }
function DateInRange(ADate, StartDate, EndDate: TDateTime; function DateInRange(ADate, StartDate, EndDate: TDateTime;
IncludeLimits: Boolean): Boolean; IncludeLimits: Boolean): Boolean;
begin begin
@ -593,6 +604,10 @@ begin
Result := (StartDate = ADate) or (EndDate = ADate); Result := (StartDate = ADate) or (EndDate = ADate);
end; end;
{ Checks whether the given time value is within the specified time interval
between StartTime and EndTime. If IncludeLimits is true then the function
result is true also if time is equal to the start or end times. Equality is
checked with a precision of 0.1 sec (see: CompareTimeEps). }
function TimeInRange(ATime, StartTime, EndTime: TDateTime; function TimeInRange(ATime, StartTime, EndTime: TDateTime;
IncludeLimits: Boolean): Boolean; IncludeLimits: Boolean): Boolean;
var var
@ -606,7 +621,30 @@ begin
else else
Result := (not equStart) and (not equEnd) and (ATime > StartTime) and (ATime < EndTime); Result := (not equStart) and (not equEnd) and (ATime > StartTime) and (ATime < EndTime);
end; end;
{=====}
{ Returns true of the two specified date/time variables have the same date part }
function SameDate(dt1, dt2: TDateTime): Boolean;
begin
Result := trunc(dt1) = trunc(dt2);
end;
// Calculates ISO week number (checked with Jan 1, 2016, which is in week 53).
function GetWeekOfYear(ADate: TDateTime): byte;
// wp: was in TvWeekView.
var
yr, dummy: word;
First: TDateTime;
begin
DecodeDate(ADate + (8 - DayOfWeek(ADate)) mod 7 - 3, yr, dummy,dummy);
First := EncodeDate(yr, 1, 1);
Result := trunc(ADate - First - 3 + (DayOfWeek(First) + 1) mod 7) div 7 + 1;
end;
// Returns true if the specified date is on the weekend.
function IsWeekend(ADate: TDateTime): Boolean;
begin
Result := (DayOfWeek(ADate) in [1, 7]);
end;
function LineToStartTime(Line: Integer; Granularity: TVpGranularity): TDateTime; function LineToStartTime(Line: Integer; Granularity: TVpGranularity): TDateTime;
begin begin
@ -676,49 +714,34 @@ begin
Result := AFont.Height; Result := AFont.Height;
end; end;
{ Returns the coordinate of the control's right boundary }
function RightOf(AControl: TControl): Integer; function RightOf(AControl: TControl): Integer;
begin begin
Result := AControl.Left + AControl.Width; Result := AControl.Left + AControl.Width;
end; end;
{ Returns the coordinate of the control's bottom boundary }
function Bottomof(AControl: TControl): Integer; function Bottomof(AControl: TControl): Integer;
begin begin
Result := AControl.Top + AControl.Height; Result := AControl.Top + AControl.Height;
end; end;
function SameDate(dt1, dt2: TDateTime): Boolean; { Replaces embedded C-style line endings (\n) by FPC line endings (#13#10, #13,
begin #10, depending on system) }
Result := trunc(dt1) = trunc(dt2);
end;
// Calculates ISO week number (checked with Jan 1, 2016, which is in week 53).
function GetWeekOfYear(ADate: TDateTime): byte;
// was in TvWeekView.
var
yr, dummy: word;
First: TDateTime;
begin
DecodeDate(ADate + (8 - DayOfWeek(ADate)) mod 7 - 3, yr, dummy,dummy);
First := EncodeDate(yr, 1, 1);
Result := trunc(ADate - First - 3 + (DayOfWeek(First) + 1) mod 7) div 7 + 1;
end;
// Returns true if the specified date is on the weekend.
function IsWeekend(ADate: TDateTime): Boolean;
begin
Result := (DayOfWeek(ADate) in [1, 7]);
end;
function DecodeLineEndings(const AText: String): String; function DecodeLineEndings(const AText: String): String;
begin begin
Result := StringReplace(AText, '\n', LineEnding, [rfReplaceAll]); Result := StringReplace(AText, '\n', LineEnding, [rfReplaceAll]);
end; end;
{ Replaces FPC line endings (#13#10, #13, #10, depending on system) by
embedded C-style line endings (\n) }
function EncodeLineEndings(const AText: String): String; function EncodeLineEndings(const AText: String): String;
begin begin
Result := StringReplace(AText, LineEnding, '\n', [rfReplaceAll]); Result := StringReplace(AText, LineEnding, '\n', [rfReplaceAll]);
end; end;
{ Makes sure that the string AText does not end with a line ending (#13#10,
#13, #10, depending on system). }
function StripLastLineEnding(const AText: String): String; function StripLastLineEnding(const AText: String): String;
begin begin
Result := AText; Result := AText;

View File

@ -287,6 +287,9 @@ type
implementation implementation
uses uses
{$IFDEF LCL}
DateUtils,
{$ENDIF}
SysUtils, LazUTF8, Dialogs, StrUtils, SysUtils, LazUTF8, Dialogs, StrUtils,
VpMonthViewPainter; VpMonthViewPainter;
@ -655,8 +658,8 @@ begin
end else end else
M := M - 1; M := M - 1;
end; end;
if (D > DaysInMonth(Y, M)) then if (D > DaysInAMonth(Y, M)) then
D := DaysInMonth(Y, M); D := DaysInAMonth(Y, M);
Date := EncodeDate(Y, M, D); Date := EncodeDate(Y, M, D);
end; end;
@ -1166,14 +1169,14 @@ begin
VK_END: VK_END:
begin begin
DecodeDate(Date, Y, M, D); DecodeDate(Date, Y, M, D);
if D = DaysInMonth(Y, M) then begin if D = DaysInAMonth(Y, M) then begin
if M = 12 then begin if M = 12 then begin
M := 1; M := 1;
Inc(Y); Inc(Y);
end else end else
Inc(M); Inc(M);
end; end;
Date := EncodeDate(Y, M, DaysInMonth(Y, M)); Date := EncodeDate(Y, M, DaysInAMonth(Y, M));
end; end;
{$IFNDEF LCL} {$IFNDEF LCL}
VK_TAB: VK_TAB:

View File

@ -296,6 +296,9 @@ type
implementation implementation
uses uses
{$IFDEF LCL}
DateUtils,
{$ENDIF}
SysUtils, StrUtils, LazUTF8, Dialogs, SysUtils, StrUtils, LazUTF8, Dialogs,
VpEvntEditDlg, VpWeekViewPainter; VpEvntEditDlg, VpWeekViewPainter;
@ -1260,8 +1263,8 @@ begin
Y := Y + 1; Y := Y + 1;
end else end else
M := M + 1; M := M + 1;
if (D > DaysInMonth(Y, M)) then if (D > DaysInAMonth(Y, M)) then
D := DaysInMonth(Y, M); D := DaysInAMonth(Y, M);
Date := EncodeDate(Y, M, D); Date := EncodeDate(Y, M, D);
end; end;
@ -1277,8 +1280,8 @@ begin
Y := Y - 1; Y := Y - 1;
end else end else
M := M - 1; M := M - 1;
if (D > DaysInMonth(Y, M)) then if (D > DaysInAMonth(Y, M)) then
D := DaysInMonth(Y, M); D := DaysInAMonth(Y, M);
Date := EncodeDate(Y, M, D); Date := EncodeDate(Y, M, D);
end; end;