Re: [Lazarus] Looking for help: Trying to add better RightToLeft support to Lazarus.

2013-11-09 Thread Avishai
If anyone wants to experiment with RightToLeft, this should get you started. 
But you must disable Themes for it to work.  Otherwise all
TWinControl.Canvas gets corrupted and can not be used.  The
TWinControl.Canvas issue is the biggest obstacle to making RightToLeft Forms
in Lazarus.  Delphi does not have this problem.

Start a new project and drop a TPageControl on the Form.  Add 2 Tabs to the
TPageControl.  Then add the CreateParams code.


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, LclType, ComCtrls;

type

  TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
  public
procedure CreateParams(var Params : TCreateParams); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

uses AviUtils, Windows;

procedure TForm1.CreateParams(var Params : TCreateParams);
begin
  inherited CreateParams(Params);
  {$IFDEF WINDOWS}
  if SysLocale.MiddleEast then 
Params.ExStyle:= Params.ExStyle or WS_EX_LAYOUTRTL; // or
WS_EX_NOINHERITLAYOUT;
  {$ENDIF}
end;

end.




--
View this message in context: 
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-Looking-for-help-Trying-to-add-better-RightToLeft-support-to-Lazarus-tp4028216p4034186.html
Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann

Am 2013-11-08 21:35, schrieb John Landmesser:
 i'm searching a pascal datetime function that simulates an Excel function: 
DateDif
 Excel for example knows the function DateDif that returns the number of 
Years, month and days between Date1 and date2.
 Date1 := 21.12.2012
 Date2 := 01.01.2013
 Result would be: 0 years, 0 moths, 11 days


I have written my own function because I wanted to
store dates in .MM.DD.MM.SS format and didn't
like any conversions back and forth between other
formats like TDateTime etc.

Find attached a time-diff routine based on some types (also included).
Maybe it is of help for you.
(Comments and function names are partly in german so you may need to change 
them).

type  ZeitTyp= record
   Jahr : word;
   Monat,
   Tag,
   Stunde,
   Minute,
   Sekunde  : byte;
   milliSek : word;
   end;
  EinAusTyp  = (Aus,Ein);
  ZeitmessTyp= array[EinAusTyp] of ZeitTyp;
  ZeitDiffTyp= record
   Negativ  : boolean; // sozusagen als Vorzeichen
   Tage,
   Stunde,
   Minute,
   Sekunde,
   milliSek : LongInt;
   end;




//---
function Schaltjahr(const Jahr : LongInt) : boolean;
// Wird true, wenn JAHR ein Schaltjahr ist

begin { Schaltjahr }
if ( (Jahr mod 4)=0 ) and
   ( (Jahr mod 100)0 ) or
   ( (Jahr mod 400)=0 ) then
   Result := true
else
   Result := false;
end;   { of --Schaltjahr--}



//---
function TimeDiffBase(var Time : ZeitmessTyp; out Fehler : boolean) : ZeitDiffTyp;
// Gibt die Zeitdifferenz der Zeiten TIME[EIN] minus TIME[AUS] zurück
var EinN,
AusN,
Wahl: EinAusTyp;
AnzahlTage : array[EinAusTyp] of LongInt;
iAnfang,
i,
Diff: LongInt;

begin { TimeDiffBase }
fillchar(Result,sizeof(Result),#0);
Fehler := false;
EinN   := Ein;
AusN   := Aus;
Result.Negativ := false;
Diff := LongInt(Time[Aus].Jahr)-Time[Ein].Jahr;
if Diff0 then Result.Negativ := true  { -- Jahresdifferenz }
else
   begin
   if Diff=0 then
  begin
  Diff := LongInt(Time[Aus].Monat)-Time[Ein].Monat;
  if Diff0 then Result.Negativ := true{ -- Monatsdifferenz }
  else
 begin
 if Diff=0 then
begin
Diff := LongInt(Time[Aus].Tag)-Time[Ein].Tag;
if Diff0 then Result.Negativ := true   { -- Tagesdifferenz }
else
   begin
   if Diff=0 then
  begin
  Diff := LongInt(Time[Aus].Stunde)-Time[Ein].Stunde;
  if Diff0 then Result.Negativ := true { -- Stundendifferenz }
  else
 begin
 if Diff=0 then
begin
Diff := LongInt(Time[Aus].Minute)-Time[Ein].Minute;
if Diff0 then Result.Negativ := true { -- Minutendifferenz }
else
   begin
   if Diff=0 then
  begin
  Diff := LongInt(Time[Aus].Sekunde)-Time[Ein].Sekunde;
  if Diff0 then Result.Negativ := true { -- Sekundendifferenz }
  else
 begin
 if Diff=0 then
begin
Diff := LongInt(Time[Aus].MilliSek)-Time[Ein].MilliSek;
if Diff0 then { -- Millisekundendifferenz }
   Result.Negativ := true;
end;
 end;
  end;
   end;
end;
 end;
  end;
   end;
end;
 end;
  end;
   end;
if Result.Negativ then
   begin
   EinN := Aus;
   AusN := Ein;
   end;
Result.Stunde   := LongInt(Time[AusN].Stunde)-Time[EinN].Stunde;
Result.Minute   := LongInt(Time[AusN].Minute)-Time[EinN].Minute;
Result.Sekunde  := LongInt(Time[AusN].Sekunde)-Time[EinN].Sekunde;
Result.millisek := LongInt(Time[AusN].milliSek)-Time[EinN].milliSek;
if (Time[EinN].JahrTime[AusN].Jahr) or
   (Time[EinN].MonatTime[AusN].Monat) or
   (Time[EinN].TagTime[AusN].Tag) then
   begin  { -- Anzahl vergangener Tage in TAGE aufsummieren }
   fillchar(AnzahlTage,sizeof(AnzahlTage),0);
   if Time[EinN].JahrTime[AusN].Jahr then
  iAnfang := Time[EinN].Jahr
   else
  iAnfang := Time[AusN].Jahr;
   for Wahl 

Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Fri, 8 Nov 2013, John Landmesser wrote:


Hi List,

i'm searching a pascal datetime function that simulates an Excel function: 
DateDif


Excel for example knows the function DateDif that returns the number of 
Years, month and days between Date1 and date2.


Date1 := 21.12.2012
Date2 := 01.01.2013

Result would be: 0 years, 0 moths, 11 days

I tried to do it on my own, but without success.

But i think there is a function out there but i don't know its name :-((


The dateutils unit contains DaysBetween, MinutesBetween, HoursBetween, etc. 
Each function exists in 2 variants: one which takes partial times, another which does complete days/hours/minutes.


See
http://www.freepascal.org/docs-html/rtl/dateutils/index-5.html

For the documentation.

Michael.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann

Am 2013-11-09 12:12, schrieb Michael Van Canneyt:
 The dateutils unit contains DaysBetween, MinutesBetween, HoursBetween, etc.
 Each function exists in 2 variants: one which takes partial times, another 
which does complete days/hours/minutes.
 See
 http://www.freepascal.org/docs-html/rtl/dateutils/index-5.html
 For the documentation.

I can't find any functions that take year/month/date as arguments.
The documentation only mentions TDateTime parameters.
(i.e. http://www.freepascal.org/docs-html/rtl/dateutils/daysbetween.html )


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread John Landmesser

On 09.11.2013 06:55, leledumbo wrote:

   Date1 := EncodeDate(2012,12,21);
   Date2 := EncodeDate(2013,01,01);


Your code Result is: 1900 Years, 1 Month, 10 days and thats incorrect.

I thought about it some time and found a solution:

Think of the age of an employe! We have now() and his birthday.
How old is he in Years , Months and days?

my code:

uses DateUtils;

function TForm1.CalcDateDif(von, bis: TDateTime): String;
var
  Year, Month, Day: longint;
  YearVon, MonthVon, DayVon : word;
  YearBis, MonthBis, DayBis : word;

begin

  DecodeDate(von, YearVon, MonthVon, DayVon);
  DecodeDate(bis, YearBis, MonthBis, DayBis);

  // whole year:
   year := YearsBetween(von,bis);

  // How many months more than months in year
   Month := MonthsBetween(von,bis) - (year * 12);

  // Special case: December of previous year as von  and not a whole 
Month until bis: 21.12.2012 until 01.01.2013

  if  (YearBis - YearVon = 1) and (MonthVon = 12) then
   begin
 Day :=  DaysBetween(von,EndOfAYear(YearVon)) + DayOfTheYear(bis);
   end
   else
  Day := DaysBetween(EnCodeDate(YearBis,MonthVon, DayVon), bis) ;

Result := IntToStr(year) + ' Jahr(e) ';

 Result := Result + IntToStr(Month) + ' Monat(e) ';

Result := Result + IntToStr(Day) + ' Tag(e) ';

end;

// I have to test that later again, but i think thats ok now?!!
// Going jogging now :-))

But i'm really wondering that Freepascal does not have such a function?!!



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Sat, 9 Nov 2013, Jürgen Hestermann wrote:


Am 2013-11-09 12:12, schrieb Michael Van Canneyt:

The dateutils unit contains DaysBetween, MinutesBetween, HoursBetween, etc.
Each function exists in 2 variants: one which takes partial times, another 

which does complete days/hours/minutes.

See
http://www.freepascal.org/docs-html/rtl/dateutils/index-5.html
For the documentation.


I can't find any functions that take year/month/date as arguments.
The documentation only mentions TDateTime parameters.
(i.e. http://www.freepascal.org/docs-html/rtl/dateutils/daysbetween.html )


So what ? Do an EncodeDate() and you're all set.
Excel also uses TDateTime, that's where the format comes from.

Michael.--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread leledumbo
Indeed that was wrong, I shouldn't exploit the internal details. Below is the
correct one (still no need for that complicated code of yours):

uses 
  SysUtils,DateUtils; 
var 
  Date1,Date2: TDate; 
  Y,M,D: Word; 
begin 
  Date1 := EncodeDate(2012,12,21); 
  Date2 := EncodeDate(2013,01,01);
  Y := YearsBetween(Date1,Date2);
  M := MonthsBetween(Date1,Date2);
  D := DaysBetween(Date1,Date2);
  WriteLn(Y,'-',M,'-',D);
end. 




--
View this message in context: 
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-DateDif-function-needed-tp4034182p4034192.html
Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty

On 11/9/2013 12:55 AM, leledumbo wrote:

uses
   SysUtils;
var
   Date1,Date2: TDate;
   Y,M,D: Word;
begin
   Date1 := EncodeDate(2012,12,21);
   Date2 := EncodeDate(2013,01,01);
   DecodeDate(Date2 - Date1,Y,M,D);
   // you have them in Y, M and D, respectively
end.


yeah, that doesn't work...

Y = 1900
M = 1
D = 10

Y should be 1 in this case...

ideally, real numbers would be used so that fractions of years, months and days 
can be determined ;)


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread John Landmesser

On 09.11.2013 14:32, leledumbo wrote:

Indeed that was wrong, I shouldn't exploit the internal details. Below is the
correct one (still no need for that complicated code of yours):

uses
   SysUtils,DateUtils;
var
   Date1,Date2: TDate;
   Y,M,D: Word;
begin
   Date1 := EncodeDate(2012,12,21);
   Date2 := EncodeDate(2013,01,01);
   Y := YearsBetween(Date1,Date2);
   M := MonthsBetween(Date1,Date2);
   D := DaysBetween(Date1,Date2);
   WriteLn(Y,'-',M,'-',D);
end.




--
View this message in context: 
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-DateDif-function-needed-tp4034182p4034192.html
Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


please test your code: 21.12.2010(!!)   01.01.2013

My code is wrong too in this case :--((



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] Windows DDE

2013-11-09 Thread Daithi Haxton
I have finally convinced my boss to have a look at Lazarus and start  
migrating our applications away from MFC ... but 
We are Windows only, currently shipping Win7. I'm using Lazarus 1.0.10  
with the bundled FPC - relatively recent. Our applications control and  
communicate with various industrial devices via Dynamic Data Exchange  
(DDE), using Microsoft's Dynamic Data Exchange Management Library  
(DDEML). Delphi in all incarnations has had DDE controls - they're  
pretty much just simple WinAPI calls, so I figured I could port them  
rather painlessly.
A week and a half later I'm sending this message - hope someone can  
help.
The basic problem seems to be in passing a string to a function in  
Windows called DdeCreateStringHandle. It's already got a def in the  
win32 tree in Free Pascal - basically this:
function DdeCreateStringHandle(Inst: DWORD; psz: PChar;  CodePage:  
Integer): HSZ; stdcall;
It doesn't seem to matter how I call it, it always registers a null  
string. I call it like this:

ServiceHSz:= DdeCreateStringHandle(Inst, StringName, CP_WINANSI);
where StringName is a const PChar and Inst is a handle returned from  
the DDEInitialize function (which I know is valid by monitoring with  
other tools). This is basically identical to the VCL from Delphi 7 and  
prior - it works find there but not with FreePascal. I'm compiling  
with Delphi mode on and get no compilation errors.


DDE works on shared memory very much like the clipboard. I'm wondering  
if there's something amiss in that regard, but am at my wits end.


Any ideas are appreciated!
Thanks,
Dave H.



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann


Am 2013-11-09 13:43, schrieb Michael Van Canneyt:

So what ? Do an EncodeDate() and you're all set.


That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Sat, 9 Nov 2013, Jürgen Hestermann wrote:



Am 2013-11-09 13:43, schrieb Michael Van Canneyt:

So what ? Do an EncodeDate() and you're all set.


That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.


Not if you store everything as a DateTime and use that. The format is such that 
it sorts naturally.

But hey, who am I to try and convince you ?

Michael.--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty

On 11/9/2013 8:32 AM, leledumbo wrote:

Indeed that was wrong, I shouldn't exploit the internal details. Below is the
correct one (still no need for that complicated code of yours):

uses
   SysUtils,DateUtils;
var
   Date1,Date2: TDate;
   Y,M,D: Word;
begin
   Date1 := EncodeDate(2012,12,21);
   Date2 := EncodeDate(2013,01,01);
   Y := YearsBetween(Date1,Date2);
   M := MonthsBetween(Date1,Date2);
   D := DaysBetween(Date1,Date2);
   WriteLn(Y,'-',M,'-',D);
end.


disregarding the above writeln being incorrect for the values represented, even 
this has problems... each value is the total value between the dates... 
YearsBetween and MonthsBetween are short by 1...



2013/01/01
2013/01/01
0 yrs, 0 mos, 0 wks, 0 dys

above is correct (of course)...

2013/01/01
2014/01/01
0 yrs, 11 mos, 52 wks, 365 dys

above should be 1 yrs, 12 mos... weeks and days are correct...

2013/01/01
2015/01/01
1 yrs, 23 mos, 104 wks, 730 dys

above should be 2 yrs, 24 mos... weeks and days are correct...


program DateDiff;

uses
  SysUtils,DateUtils;

var
  Date1,Date2: TDate;
  Yr,Mo,Wk,Dy: Integer;

begin
  Date1 := EncodeDate(2013,01,01);
  Date2 := EncodeDate(2015,01,01);
  writeln(FormatDateTime('/MM/DD HH:NN:SS.ZZZ',Date1));
  writeln(FormatDateTime('/MM/DD HH:NN:SS.ZZZ',Date2));
  Yr := YearsBetween(Date1,Date2);
  Mo := MonthsBetween(Date1,Date2);
  Wk := WeeksBetween(Date1,Date2);
  Dy := DaysBetween(Date1,Date2);
  writeln(Yr,' yrs, ',Mo,' mos, ',Wk,' wks, ',Dy,' dys');
end.


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann


Am 2013-11-09 16:54, schrieb Michael Van Canneyt:

On Sat, 9 Nov 2013, Jürgen Hestermann wrote:

That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.

Not if you store everything as a DateTime and use that. The format is such that 
it sorts naturally.


Storing dates as floats has a lot of drawbacks.
It's inaccurate, you always need a starting date and get other problems.
I shudder when thinking about Excels 1900 and 1904 based dates
where suddenly all my dates in the sheet where changed by 4 years
because the base has changed. ;-(


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Windows DDE

2013-11-09 Thread Ludo Brands
On 11/09/2013 03:53 PM, Daithi Haxton wrote:
 It doesn't seem to matter how I call it, it always registers a null
 string. I call it like this:
 ServiceHSz:= DdeCreateStringHandle(Inst, StringName, CP_WINANSI);
 where StringName is a const PChar and Inst is a handle returned from the
 DDEInitialize function (which I know is valid by monitoring with other
 tools). This is basically identical to the VCL from Delphi 7 and prior -
 it works find there but not with FreePascal. I'm compiling with Delphi
 mode on and get no compilation errors.
 

afaik DDEInitialize is defined slightly different in Freepascal from Delphi.

This creates a valid DDE string handle for me:

{$mode delphi}
uses ..., windows;

var
  Res: UINT;
  g_idInst: DWORD;
  g_hszAppName: HSZ;

const DMLERR_NO_ERROR=0;

  function DDECallback(CallType, Fmt: UINT; Conv: HConv; hsz1, hsz2: HSZ;
  Data: HDDEData; Data1, Data2: DWORD): HDDEData; stdcall;
begin
//
end;

begin
  g_idInst:=0;
  Res:=DdeInitialize(@g_idInst, DdeCallback, APPCLASS_STANDARD, 0);
  if Res = DMLERR_NO_ERROR then
g_hszAppName:= DdeCreateStringHandle(g_idInst,'DDEServer',CP_WINANSI);
end.

If g_hszAppName is 0 then call
  DdeGetLastError(g_idInst);
to see what the last error is.

Ludo

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty


digging deeper to work directly with YearsBetween and MonthsBetween shows that 
they seem to be missing the usual +0.5 generally used to ensure that rounding 
is properly handled...


the following two pairs of routines work to give the desired output...

*this pair uses Trunc((X)+.05) instead of the original Trunc(X)*

Function YearsBetween(const ANow, AThen: TDateTime): Integer;
begin

Result:=Trunc(((Abs(MyDateTimeDiff(ANow,AThen))+TDateTimeEpsilon)/ApproxDaysPerYear)+0.5);
end;

Function MonthsBetween(const ANow, AThen: TDateTime): Integer;
begin

Result:=Trunc(((Abs(MyDateTimeDiff(ANow,AThen))+TDateTimeEpsilon)/ApproxDaysPerMonth)+0.5);
end;

note the additional '(' after 'Trunc' and the closing '+0.5)' which handles the 
rounding as compared to the original routines in DateUtil.inc...



*OR this pair using Round() instead of the original Trunc(X) or the above 
Trunc((X)+0.5)*



Function YearsBetween(const ANow, AThen: TDateTime): Integer;
begin

Result:=Round((Abs(MyDateTimeDiff(ANow,AThen))+TDateTimeEpsilon)/ApproxDaysPerYear);
end;

Function MonthsBetween(const ANow, AThen: TDateTime): Integer;
begin

Result:=Round((Abs(MyDateTimeDiff(ANow,AThen))+TDateTimeEpsilon)/ApproxDaysPerMonth);
end;


i don't know which would be better to use in this case but one should be applied 
to the existing routines in DateUtil.inc to fix the error in them ;)


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann

Am 2013-11-09 18:42, schrieb waldo kitty:
 
Result:=Trunc(((Abs(MyDateTimeDiff(ANow,AThen))+TDateTimeEpsilon)/ApproxDaysPerYear)+0.5);
 end;

I thought that correct results should be calculated, not only approximate 
values.
What is ApproxDaysPerYear?
A leap year has 266 days and others 365 and this should be considered.
Calculations based on floats seem not very reliable.


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Sat, 9 Nov 2013, Jürgen Hestermann wrote:



Am 2013-11-09 16:54, schrieb Michael Van Canneyt:

On Sat, 9 Nov 2013, Jürgen Hestermann wrote:

That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.
Not if you store everything as a DateTime and use that. The format is such 
that it sorts naturally.


Storing dates as floats has a lot of drawbacks.
It's inaccurate, you always need a starting date and get other problems.


Can you prove this statement ?

I use this type since more than 15 years, never experienced a glitch.

Of course, I didn't have to represent stardate XYZ.NMO, but in my opinion, 
TDateTime is usable for 99,99% of all use cases.

Michael.--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Sat, 9 Nov 2013, waldo kitty wrote:



digging deeper to work directly with YearsBetween and MonthsBetween shows 
that they seem to be missing the usual +0.5 generally used to ensure that 
rounding is properly handled...


You misunderstood these functions.

There is no rounding necessary. The routines are correct.

Only FULL years/months/day must be counted.

See the documentation in e.g.

http://www.freepascal.org/docs-html/rtl/dateutils/yearsbetween.html

If you want partial years counted, you need the *Span functions.

http://www.freepascal.org/docs-html/rtl/dateutils/yearspan.html

Michael.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Jürgen Hestermann

Am 2013-11-09 18:31, schrieb Michael Van Canneyt:
 On Sat, 9 Nov 2013, Jürgen Hestermann wrote:
 Storing dates as floats has a lot of drawbacks.
 It's inaccurate, you always need a starting date and get other problems.
 Can you prove this statement ?

Well, aren't the current mails about incorrect YearsBetween calculation proof 
enough?
If you need to use an approximate value for days in the year then some is wrong 
IMO.
For the same difference between two time floats it can be a full year or not
depending on whether a leap year is included or not.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Michael Van Canneyt



On Sat, 9 Nov 2013, Jürgen Hestermann wrote:


Am 2013-11-09 18:31, schrieb Michael Van Canneyt:

On Sat, 9 Nov 2013, Jürgen Hestermann wrote:

Storing dates as floats has a lot of drawbacks.
It's inaccurate, you always need a starting date and get other problems.

Can you prove this statement ?


Well, aren't the current mails about incorrect YearsBetween calculation proof 
enough?


They are not incorrect. 
The reporter didn't understand what they are supposed to do.


If you need to use an approximate value for days in the year then some is 
wrong IMO.


Not if it is clearly documented.

Michael.--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Benito van der Zander

if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.

nonsense.

Store it as packed record word-byte-byte = int and you have faster 
comparisons than TDateTime!


On 11/09/2013 04:23 PM, Jürgen Hestermann wrote:


Am 2013-11-09 13:43, schrieb Michael Van Canneyt:

So what ? Do an EncodeDate() and you're all set.


That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread John Landmesser

On 08.11.2013 21:35, John Landmesser wrote:

Hi List,

i'm searching a pascal datetime function that simulates an Excel 
function: DateDif


Excel for example knows the function DateDif that returns the number 
of Years, month and days between Date1 and date2.


Date1 := 21.12.2012
Date2 := 01.01.2013

Result would be: 0 years, 0 moths, 11 days

I tried to do it on my own, but without success.

But i think there is a function out there but i don't know its name :-((

Thanks for your tipps

John

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus



Found a solution  in Jedi: /jvcl/run/JvJCLUtils.pas

procedure DateDiff(Date1, Date2: TDateTime; var Days, Months, Years: Word
  );
var
  DtSwap: TDateTime;
  Day1, Day2, Month1, Month2, Year1, Year2: Word;
begin
  if Date1  Date2 then
  begin
DtSwap := Date1;
Date1 := Date2;
Date2 := DtSwap;
  end;
  DecodeDate(Date1, Year1, Month1, Day1);
  DecodeDate(Date2, Year2, Month2, Day2);
  Years := Year2 - Year1;
  Months := 0;
  Days := 0;
  if Month2  Month1 then
  begin
Inc(Months, 12);
Dec(Years);
  end;
  Inc(Months, Month2 - Month1);
  if Day2  Day1 then
  begin
// von mir auskommentiert Inc(Days, DaysPerMonth(Year1, Month1));
Inc(Days, DaysInAMonth(Year1, Month1));
if Months = 0 then
begin
  Dec(Years);
  Months := 11;
end
else
  Dec(Months);
  end;
  Inc(Days, Day2 - Day1);
end;

**

Seems to calculate ok.
Now i'll try to understand what it is doing :-))


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


[Lazarus] Centered elements in autosize enabled panel. Possible?

2013-11-09 Thread Valdas Jankūnas

Hello,

I want to create this layout:
- form has a Panel;
- Autosize of Panel is True;
- Panel has Controls with various heights;
- every Control in Panel must be centered vertically.

I tried this (trough Anchor editor):
- Control2 centered to Control1;
- Control1 centered to Panel.
But then Panel shrinks to Height=2 (circular align happens?).

Is it possible to create mentioned layout (preferably not through code)?


Sorry for bad English.

--
  Valdas Jankūnas

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Centered elements in autosize enabled panel. Possible?

2013-11-09 Thread Avishai
Have you tried using BorderSpacing?  I think you can get what you want using
Left and Right BorderScaping.  I'll give it a try.



--
View this message in context: 
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-Centered-elements-in-autosize-enabled-panel-Possible-tp4034210p4034211.html
Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Centered elements in autosize enabled panel. Possible?

2013-11-09 Thread Avishai
OK.  I tried putting 2 Labels Align:= alLeft.  For both Labels I set
BorderSpacing Left and Right := 10 and Layout := tlCenter.  Then I set
Panel.AutoSize := True.  It looks like it does what you want.



--
View this message in context: 
http://free-pascal-lazarus.989080.n3.nabble.com/Lazarus-Centered-elements-in-autosize-enabled-panel-Possible-tp4034210p4034212.html
Sent from the Free Pascal - Lazarus mailing list archive at Nabble.com.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Centered elements in autosize enabled panel. Possible?

2013-11-09 Thread Valdas Jankūnas

2013.11.09 22:52, Avishai rašė:

OK.  I tried putting 2 Labels Align:= alLeft.  For both Labels I set
BorderSpacing Left and Right := 10 and Layout := tlCenter.  Then I set
Panel.AutoSize := True.  It looks like it does what you want.


It works! Even with autosized Buttons or Edits.

Thanks!


--
  Valdas Jankūnas

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] Centered elements in autosize enabled panel. Possible?

2013-11-09 Thread Avishai
Glad I could help :)


On Sat, Nov 9, 2013 at 11:13 PM, Valdas Jankūnas zmu...@gmail.com wrote:

 2013.11.09 22:52, Avishai rašė:

 OK.  I tried putting 2 Labels Align:= alLeft.  For both Labels I set
 BorderSpacing Left and Right := 10 and Layout := tlCenter.  Then I set
 Panel.AutoSize := True.  It looks like it does what you want.


 It works! Even with autosized Buttons or Edits.

 Thanks!


 --
   Valdas Jankūnas

 --
 ___
 Lazarus mailing list
 Lazarus@lists.lazarus.freepascal.org
 http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus




-- 
Shalom,
Avishai
avishai.g...@gmail.com
אבישי גוֹר
--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty

On 11/9/2013 1:41 PM, Michael Van Canneyt wrote:



On Sat, 9 Nov 2013, waldo kitty wrote:



digging deeper to work directly with YearsBetween and MonthsBetween shows that
they seem to be missing the usual +0.5 generally used to ensure that
rounding is properly handled...


You misunderstood these functions.

There is no rounding necessary. The routines are correct.

Only FULL years/months/day must be counted.


ahhh...


See the documentation in e.g.

http://www.freepascal.org/docs-html/rtl/dateutils/yearsbetween.html


yes, i've been digging in them all day since this thread came up ;)


If you want partial years counted, you need the *Span functions.

http://www.freepascal.org/docs-html/rtl/dateutils/yearspan.html


i'll have to look at those... i've been looking for something that can (without 
having to reinvent the wheel) show that the difference between


  2013 01 01 00:00:00.000 and
  2013 01 01 00:00:00:001 is
  0 Years, 0 Months, 0 Days, 0 Hours, 0 Minutes, 0 Seconds, 1 Msecond

whereas

  2013 01 01 00:00:00.000 and
  2013 01 01 00:00:00:100 is
  0 Years, 0 Months, 0 Days, 0 Hours, 0 Minutes, 0 Seconds, 100 Msecond

and

  2013 01 01 00:00:00.000 and
  2013 01 01 00:00:01:001 is
  0 Years, 0 Months, 0 Days, 0 Hours, 0 Minutes, 1 Seconds, 1 Msecond

and

  2013 01 01 00:00:00.000 and
  2014 02 02 01:01:01:001 is
  1 Years, 1 Months, 1 Days, 1 Hours, 1 Minutes, 1 Seconds, 1 Msecond

and also being able to include Weeks in there if we are eg: 1, 2 or 3 weeks into 
a month...


i will take a look at the SPAN functions and see if they will provide what i've 
been (silently) looking for ;)


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty

On 11/9/2013 1:48 PM, Jürgen Hestermann wrote:

Am 2013-11-09 18:31, schrieb Michael Van Canneyt:
  On Sat, 9 Nov 2013, Jürgen Hestermann wrote:
  Storing dates as floats has a lot of drawbacks.
  It's inaccurate, you always need a starting date and get other problems.
  Can you prove this statement ?

Well, aren't the current mails about incorrect YearsBetween calculation proof
enough?


i misunderstood the given functions... sorry :?


If you need to use an approximate value for days in the year then some is wrong
IMO.


i have been working on this most all day and there's no way around it with 
simple functions... they must be more intricate than what i've seen or created 
so far...



For the same difference between two time floats it can be a full year or not
depending on whether a leap year is included or not.


and there's the rub... if you want the difference between two dates and times, 
how do you calculate if there is a leap year involved, which year of the date is 
involved and how do you feed that to the *Between routines? you can't from what 
i've seen... however the *Span routines i've been pointed to may very well 
handle this...


what i've seen is like comarping this

2013/01/01 00:00:00.000
2014/01/01 00:00:00.001

and getting this
MilliSecondsBetween(A1,A2) = 3153601

but this is an estimated value because

RealMSPerYear = 3155760

is what you get with 365.25 days per year...

but then looking at those two values, you cannot tell if a leap year is involved 
in there or not... much less if there are two or more leap years...


back in the day, routines that i used to do this in TP/BP converted the 
date/time values to julian date values, worked on them for the difference and 
then converted back to individual year, months, day, etc... but then things 
break when traversing over period count changes or trying to go between 
different calendar formats... it was ugly then and still ugly now... i just hope 
that what i had then is available now via built-in library routines or is easily 
built from the library routines ;)


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread waldo kitty

On 11/9/2013 1:54 PM, Michael Van Canneyt wrote:

On Sat, 9 Nov 2013, Jürgen Hestermann wrote:

If you need to use an approximate value for days in the year then some is
wrong IMO.


Not if it is clearly documented.


actually, in the name of accuracy, it is highly desirable... being able to 
determine if a date range spans one or more leap years is important... too bad 
there's not a set routine for when leap seconds are added... things like this 
really rattle the cages of those of us with OCD where accuracy in values is 
highly desirable ;)


FWIW: i discovered, later, that my +0.05 didn't work as desired in all 
situations :(  gonna finish eating and reading emails and then maybe go digging 
again O:)


--
NOTE: No off-list assistance is given without prior approval.
  Please keep mailing list traffic on the list unless
  private contact is specifically requested and granted.

--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus


Re: [Lazarus] DateDif function needed

2013-11-09 Thread Hans-Peter Diettrich

Jürgen Hestermann schrieb:


Am 2013-11-09 13:43, schrieb Michael Van Canneyt:

So what ? Do an EncodeDate() and you're all set.


That would be a real performance hit (i.e. when sorting by date)
if you have stored dates in year, month, day... format.
Each comparison then needs multiple convertions each time.


Not with ISO date format (-mm-dd), where a single string compare is 
sufficient. But certainly a string compare is more expensive than a 
comparison of two Real values.


DoDi


--
___
Lazarus mailing list
Lazarus@lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus