Title: Date aritmetic, using a TDateTimePicker Component
Question: Some jobs need to be done 24 hours a day. Generally in this case there are 4 crews ,which have an alternate day, evening and night shift.
A typical shift patern would be:
5 morning - 1 free day - 5 evening - 2 free days - 5 night - 2 free days, totalling a work cyclus of 20 days.
Problem: how does a shift worker could know his assignment on a future date ?
Answer:
Approach:
First we have to map the schedule from a reference date, until we got the same patern.
In this case we will need a small database with 20 records (reference 0 --- 19)
ref A B C D
0 4M 3E 1N free
1 5M 4E 2N free
2 free 5E 3N 1M
3 1E free 4N 2M
4 2E free 5N 3M
5 3E 1N free 4M
6 4E 2N free 5M
7 5E 3N 1M free
8 free 4N 2M 1E
9 free 5N 3M 2E
etc..
LEGEND
4M = fourth morning shift
1E = first evening shift
2N = second night shift
free = off day
To find the assignment on a certain day:
1) Calculate the difference between the future day and the reference day
2) Calculate the mod of the difference and 20 x = diff mod 20
3) Look Up x in the ref column in the table to find the assignment for each shift (This is done with a parameterized query)
Components used
TDateTimePicker
TQuery
TDataSource
TDBGrid
2x TLabel
SQL property of query1:
Select A, B, C, D from "Working.DB" Working where Ref =: val
I used here a paradox table
Activate the OnChange and the OncloseUp events of the DateTimepicker to fire the query
-----------------------------------------------
unit ShiftMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, DBGrids, Db, DBTables, ComCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Future: TDateTimePicker;
Query1: TQuery;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
procedure FormCreate(Sender: TObject);
procedure FutureChange(Sender: TObject);
procedure CalcDates;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Days, x : integer;
temp : string;
RefDate :TDate;
implementation
{$R *.DFM}
procedure Tform1.CalcDates;
Begin
Days := Round (Future.date - refdate);
str(Days , temp);
label1.Caption := 'Difference = '+temp + ' days';
x := Days mod 20;
str(x, temp);
label2.Caption := 'rest = '+temp + ' days';
// search for x in the data base
with Query1 do
begin
Close;
ParamByName('val').AsInteger := X;
Open;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Refdate := 36891;
// 31 december 2000 is the reference date
CalcDates;
end;
procedure TForm1.FutureChange(Sender: TObject);
begin
CalcDates;
end;
end.
With some modifications the code also can be used to generate a printed Shift schedule for a given period.