|
Date / Time
Date conversion - adding century
Days between two dates
Set system date and time (of the computer) using Delphi
Number of current week
How to reset a Timer halfway thru
Convert date to number in milliseconds
Difference between two dates
Time problems
EncodeDate
Time difference
Date Math
Time Variable
Date Conversion
Calcutation of Easter
Dates and weeks
Converting date to week
Adding time and date stamp to memos
Date conversion - adding century
Question
I have to convert a Date from the format 'DD/MM/YY' to 'DDMMYYYY'
Answer
A:
LongDate := FormatDateTime('ddmmyyyy', StrToDate(ShortDate));
This converts a date held in the format specified in the
Control Panel's short date format (which could well be
DD/MM/YY) to the format specified in the Format string
(in the example DDMMYYYY).
If the DD/MM/YY is an input field, and DDMMYYYY is
a database field, it might clever to use code like this as
it should still work correctly for a user who wants to use
a different date format, and accordingly specifies this in
his/her Control Panel.
(Of course YYYYMMDD would normally be better than
DDMMYYYY as a database field because it would be
easier to sort records to date sequence.
Days between two dates
Question
I have two dates and want to know how many days separate them.
Answer
A:
VARIABLES:
Year1, Month1, Day1,
Year2, Month2, Day2,
YearResult, MonthResult, DayResult: Word;
TDay1, TDay2, DateDiff: TDateTime;
CODE:
TDay1 := EncodeDate(Year1, Month1, Day1);
TDay2 := EncodeDate(Year2, Month2, Day2);
DateDiff := TDay2 - TDay1; {assuming TDay2 is later than TDay1}
DecodeDate(DateDiff, YearResult, MonthResult, DayResult);
DateDiff actually is a LongInt (albeit a TDateTime object) representing the
difference in days.
Set system date and time (of the computer) using Delphi
Question
I would like know how it's possible set system date and time (of the computer)
using Delphi.
Answer
A:
Yes you can. Use this code:
Procedure settime(hour, min, sec, hundreths : byte); assembler;
asm
mov ch, hour
mov cl, min
mov dh, sec
mov dl, hundreths
mov ah, $2d
int $21
end;
Procedure setdate(Year : word; Month, Day : byte); assembler;
asm
mov cx, year
mov dh, month
mov dl, day
mov ah, $2b
int $21
end;
Number of current week
Question
I need to calculate the week number - does anyone know of a debugged formula
to do this?
Answer
A:
There are 2 other functions included which are required for our
function. One checks for a Leap year, the other returns the # of days
in a month (checking the leap year) and the 3rd is the one you want,
the week of the year.
{***************************************************************************}
function kcIsLeapYear( nYear: Integer ): Boolean;
begin
Result := (nYear mod 4 = 0) and ((nYear mod 100 <> 0) or (nYear mod
400 = 0));
end;
{***************************************************************************}
function kcMonthDays( nMonth, nYear: Integer ): Integer;
const
DaysPerMonth: array[1..12] of Integer = (31, 28, 31, 30, 31, 30, 31,
31, 30, 31, 30, 31);
begin
Result := DaysPerMonth[nMonth];
if (nMonth = 2) and kcIsLeapYear(nYear) then Inc(Result);
end;
{***************************************************************************}
function kcWeekOfYear( dDate: TDateTime ): Integer;
var
X, nDayCount: Integer;
nMonth, nDay, nYear: Word;
begin
nDayCount := 0;
deCodeDate( dDate, nYear, nMonth, nDay );
For X := 1 to ( nMonth - 1 ) do
nDayCount := nDayCount + kcMonthDays( X, nYear );
nDayCount := nDayCount + nDay;
Result := ( ( nDayCount div 7 ) + 1 );
end;
How to reset a Timer halfway thru
Question
My timer is set to 5000 (5 seconds), halfway, thru' this, an event occurs
and I need to reset this Timer back to time zero again...
Answer
A:
Timer1.Enabled := False;
Timer1.Enabled := True;
This will reset the timer for its full duration.
BTW, changing the interval (to a different value) also resets the
timer.
A:
You may enable or disable your timer component, setting its
property, like this:
Timer1.Enabled := True; { or False, if you want to disable it }
But it will still continue with its 5 secs. If you want to change this,
set another property, the interval one, like this:
Timer1.Interval := 100;
Convert date to number in milliseconds
Question
PDOXWin allows conversion of a dateTime to a number in milliseconds. Am
trying to write code in Delphi to do the same procedure. I have done the
following which results in date format:
procedure TForm1.Table1NewRecord(DataSet: TDataset);
begin
Table1.FieldByName('MyField').AsDateTime :=
EncodeDate(9999, 12, 31) - Now;
end;
Anyone suggest how the code should read if 'MyField' were a number field
and AsDateTime were to change to AsInteger?
How would I get a number that is in milliseconds?
Answer
A:
EncodeDate returns a TDateTime object, which is just a double. To get the
milliseconds since 1/1/0001 multiply the result by 86400000.0 Better yet, first
substract from a more recent base date, so as not to cause overflow.
Difference between two dates
Question
Anybody know where I can get hold of some functions for date manipulation?
I need something like the DateDiff() function in VB that returns the
number of months between dates.
Also, how about a function to calculate Present Value for a string of cash
flows?
Answer
A:
For DateDiff:
Have you looked at the DecodeDate function? It's not exactly the same, but
with it you may be able to get the result by creating your own custom function.
For Present Value
function PresentValue(const cashflows : array of double; { the cash flows
in consecutive order nearest is at cashflows[0] }
n : integer; { number of cash flows in array }
rate : double; { the percent rate per period }
atbegin : boolean) : double; { true if cash flow at beginning of
period, false if at end }
var
i : integer;
factor : double;
begin
factor := (1 + rate / 100.0);
result := 0;
for i := n - 1 downto 0 do
result := (result + cashflows[n]) / factor;
if atbegin then
result := result * factor;
end;
Time problems
Question
Just tried to use the 'typed constant Time24Hour' as shown in the
EncodeTime function. Can't seem to find this constant in SysUtils or
anywhere else.
Answer
A:
I found Time24Hour in the Help system, as you indicated. But...
here is the code for EncodeTime in SysUtils.Pas file:
function DoEncodeTime(Hour, Min, Sec, MSec: Word; var Time: TDateTime): Boolean;
begin
Result := False;
if (Hour < 24) and (Min < 60) and (Sec < 60) and (MSec < 1000) then
begin
Time := (LongMul(Hour * 60 + Min, 60000) + Sec * 1000 + MSec) / MSecsPerDay;
Result := True;
end;
end;
function EncodeTime(Hour, Min, Sec, MSec: Word): TDateTime;
begin
if not DoEncodeTime(Hour, Min, Sec, MSec, Result) then
ConvertError(LoadStr(STimeEncodeError));
end;
As you can see, any Time24Hour check is present. I looked it in the Browser
too. Nothing!
So, I thing is better conclude that Time24Hour is an old intention of
Borland-staff, aborted in Code but not in Help files. Does't you think so?
EncodeDate
Question
Could anyone give me the syntax for converting text to and
from a Paradox Date field value? EncodeDate(xx,xx,xx)?
Answer
TheDateField.AsString := TheDateString;
TheDateString := TheDateField.AsString;
this will do a convert just like DateToStr and StrToDate. Similar to
TheDateField.AsDateTime := StrToDate(TheDateString);
TheDateString := DateToStr(TheDateField.AsDateTime);
Time difference
Question
var
TimeStart : TDateTime;
procedure TimeTaken;
var
tt : Double; {Have tried this as TDateTime}
begin
tt := Now - TimeStart;
Edit1.Text := FloatToStr(tt);
end;
OK, now matter what I do tt = Now not the difference. What am I missing.
Answer
A:
I don't know when you execute TimeTaken.. Did you give some delayed time before
executing TimeTaken after execute SetTimeStart? If didn't then no wonder it
tt=Now..
I've tried your code, with some minor changes... and I always got the difference
between Now and TimeStart. But, I declare tt as TDateTime not as Double and
using OnTimer event to execute TimeTaken procs.
You can check it by trying the example below.
{*******************************************************************
FILE : TIMEEX.PAS
NOTE : Create form which contains 1 TTimer, and 6 TLabel.
Set OnTimer Event of TTimer to TForm.Timer1.Timer
********************************************************************}
unit Time;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel; {Caption : 'Start :'}
Label2: TLabel;
Label3: TLabel; {Caption : 'Time : '}
Label4: TLabel;
Label5: TLabel; {Caption : 'Elapsed time:'}
Label6: TLabel;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
TimeStart : TDateTime;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
TimeStart := Now;
Label2.Caption := TimeToStr(Now);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
tt : TDateTime;
begin
Label4.Caption := TimeToStr(Now);
tt:= Now - TimeStart;
Label6.Caption:= TimeToStr(tt);
end;
end.
Date Math
Question
Is there a function that will do simple date addition or will I have to
write a routine for it?
Answer
A:
procedure TForm1.MaskEdit1Exit(Sender: TObject);
var
y, m, d : word;
begin
decodedate(strtodate(maskedit1.text) + 11, y, m, d);
maskedit2.text := inttostr(m) + '/' + inttostr(d) + '/' + inttostr(y);
end;
Time Variable
Question
How can I keep the elapsed time for a certain process?
For Example: Beginning Time: 10:45:34, Current Time: 10:48:39
Elapsed Time = 00:03:05
Answer
Use variables of type TDateTime.
procedure TForm1.XXXXXXXClick(Sender: TObject);
var StartTime, EndTime, ElapsedTime :TDateTime;
begin
StartTime := Now;
{Put your code here}
EndTime := Now;
ElapsedTime := EndTime - StartTime;
Label1.Caption := TimeToStr(ElapsedTime);
end;
A:
{now this is from memory, but it should be a good place to start. }
var
before,
after,
elapsed : TDateTime;
Ehour, Emin, Esec, Emsec : WORD;
...
before := now;
some_process();
after := now;
elapsed := after - before;
decodetime(elapsed, Ehour, Emin, Esec, Emsec);
now Ehour:Emin:Esec.Emsec will hold the elapsed time {give or take a little;).
A:
This is what I do. fStartWhen hold the date/time when the
process was started. (fStartWhen := NOW). OneSecond is
a constant defined as 1/24/3600. (Yes, this program can
run for days. Even a fast P5 can get overwhelmed with
too much data!)
PROCEDURE TformDBLoad.UpdateTime;
VAR Delta :TDateTime
;
BEGIN
; fLastUpdate := NOW
; IF ABS( fStartWhen - fLastUpdate ) < OneSecond THEN EXIT
; Delta := fLastUpdate - fStartWhen
; doElapsedTime.Caption := FORMAT( '%1.0f days %s',
[INT(Delta),FORMATDATETIME('hh:nn:ss', FRAC(Delta))] )
END;
Date Conversion
Question
I may be brain dead here but I'm having trouble finding a simple way to
convert a date string given to me like this '1996-06-03 00.00.00' in to a
string of the format indecated by the Date/Time Formatting Variable:
ShortDateFormat.
Answer
procedure TForm1.Button1Click(Sender: TObject);
var
st,
formatsave : string;
DT : TDateTime;
begin
st := Edit1.text; // '1996-06-03 00.00.00'
formatsave := ShortDateFormat;
ShortDateFormat := 'yyyy.mm.dd hh.mm.ss';
while pos ('-', st) > 0 do
st [pos ('-', st)] := '.';
DT := StrToDateTime (st);
ShortDateFormat := formatsave;
Label1.Caption := DateTimeToStr (DT);
end;
Calcutation of Easter
Question
I've to calculate easter in a project. I found some old
pascal code from years back. I tried to use it, and it
works ok for this year but not for next year (1997).
Answer
function Easter (Year: Integer): TDateTime;
{----------------------------------------------------------------}
{ Calculates and returns Easter Day for specified year. }
{ Originally from Mark Lussier, AppVision . }
{ Corrected to prevent integer overflow if it is inadvertently }
{ passed a year of 6554 or greater. }
{----------------------------------------------------------------}
var
nMonth, nDay, nMoon, nEpact, nSunday,
nGold, nCent, nCorx, nCorz: Integer;
begin
{ The Golden Number of the year in the 19 year Metonic Cycle: }
nGold := (Year mod 19) + 1;
{ Calculate the Century: }
nCent := (Year div 100) + 1;
{ Number of years in which leap year was dropped in order... }
{ to keep in step with the sun: }
nCorx := (3 * nCent) div 4 - 12;
{ Special correction to syncronize Easter with moon's orbit: }
nCorz := (8 * nCent + 5) div 25 - 5;
{ Find Sunday: }
nSunday := (Longint(5) * Year) div 4 - nCorx - 10;
{ ^ To prevent overflow at year 6554}
{ Set Epact - specifies occurrence of full moon: }
nEpact := (11 * nGold + 20 + nCorz - nCorx) mod 30;
if nEpact < 0 then
nEpact := nEpact + 30;
if ((nEpact = 25) and (nGold > 11)) or (nEpact = 24) then
nEpact := nEpact + 1;
{ Find Full Moon: }
nMoon := 44 - nEpact;
if nMoon < 21 then
nMoon := nMoon + 30;
{ Advance to Sunday: }
nMoon := nMoon + 7 - ((nSunday + nMoon) mod 7);
if nMoon > 31 then
begin
nMonth := 4;
nDay := nMoon - 31;
end
else
begin
nMonth := 3;
nDay := nMoon;
end;
Easter := EncodeDate(Year, nMonth, nDay);
end; {Easter}
Dates and weeks
Question
Id like to retrieve a week number (1-52) from a date as "1996-06-25".
also I'd like to set a week and a year and get the matching dates for the
at week.
Answer
I have a program that makes something near what you want. It tells which
week is the date of, and the corresponding day of the week. You will have
to implement the calculation of the week limit dates. Besides, the date
format it handles is "06/25/1996".
You have to create form named "Forma", with an TEdit named "Edit1",
four labels, and un button named "GetWeekBtn". You must make sure
that the event OnCreate of the form is set to FormCreate.
I hope it is useful for you, any comments will be welcome.
unit Forma;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls;
type
TForma1 = class(TForm)
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
GetWeekBtn: TButton;
Label4: TLabel;
procedure GetWeekBtnClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Function HowManyDays(pYear,pMonth,pDay:word):integer;
public
{ Public declarations }
end;
var
Forma1: TForma1;
implementation
{$R *.DFM}
Uses Inifiles;
procedure TForma1.FormCreate(Sender: TObject);
var WinIni:TInifile;
begin
WinIni:=TIniFile.Create('WIN.INI');
WinIni.WriteString('intl','sShortDate','MM/dd/yyyy');
WinIni.Free;
end;
Function TForma1.HowManyDays(pYear,pMonth,pDay:word):integer;
var Sum:integer;
pYearAux:word;
begin
Sum:=0;
if pMonth>1 then Sum:=Sum+31;
if pMonth>2 then Sum:=Sum+28;
if pMonth>3 then Sum:=Sum+31;
if pMonth>4 then Sum:=Sum+30;
if pMonth>5 then Sum:=Sum+31;
if pMonth>6 then Sum:=Sum+30;
if pMonth>7 then Sum:=Sum+31;
if pMonth>8 then Sum:=Sum+31;
if pMonth>9 then Sum:=Sum+30;
if pMonth>10 then Sum:=Sum+31;
if pMonth>11 then Sum:=Sum+30;
Sum:=Sum + pDay;
if ((pYear - (pYear div 4)*4)=3D0) and
(pMonth>2)then
inc(Sum);
HowManyDays:=Sum;
end; { HowManyDays }
procedure TForma1.GetWeekBtnClick(Sender: TObject);
var
ADate: TDateTime;
EditAux:String;
Week,year,month,day:Word;
begin
EditAux:=Edit1.Text;
ADate := StrToDate(EditAux);
Label1.Caption := DateToStr(ADate);
DecodeDate(Adate,Year,Month,Day);
Case DayOfWeek(ADate) of
1: Label4.Caption:='Sunday';
2: Label4.Caption:='Monday';
3: Label4.Caption:='Tuesday';
4: Label4.Caption:='Wednesday';
5: Label4.Caption:='Thursday';
6: Label4.Caption:='Friday';
7: Label4.Caption:='Saturday';
end
Week:=(HowManyDays(year,month,day) div 7) +1;
Label3.Caption:='Week No. '+IntToStr(Week);
end;
end.
Converting date to week
Question
I need to be able to tell which week number a given date will fall in for
the future, including leap year conversions.
Answer
procedure TForm1.Button1Click(Sender: TObject);
var frstDay,toDay : TDateTime; week : Integer;
begin
frstDay := StrToDate('1/1/96');
toDay := StrToDate(Edit1.Text);
week := Trunc((toDay - frstDay) / 7) + 1;
Label1.Caption := IntToStr(week);
end;
Adding time and date stamp to memos
Question
How to add time and date stamp to memos?
Answer
{ The following code inserts a date/time stamp into a memo field. }
Var
s : string ;
begin
s := DateToStr( Date ) + ' ' + TimeToStr( Time ) + ' :' ;
Memo1.Lines.Insert( 0, s ) ;
Memo1.SetFocus ;
Memo1.SelStart := Length( s ) ;
Memo1.SelLength := 0 ;
|