Author Topic: Date and time functions  (Read 857 times)

0 Members and 1 Guest are viewing this topic.

Offline JotEmI

  • Soldier
  • **
  • Posts: 188
Date and time functions
« on: March 15, 2013, 04:53:12 am »
I'm working on a new mod and found myself in need to do some date and time calculations (like comparing two dates, adding one date to another, etc.). As far as I know ScriptCore doesn't support TDateTime type or any of the date & time functions (except FormatDate()). So, before I roll up my sleeves and implement them on my own I'd like to ask if anyone already tried it and could share some code to speed up my work.


Offline Falcon`

  • Flagrunner
  • ****
  • Posts: 792
  • A wanted lagger
Re: Date and time functions
« Reply #1 on: March 15, 2013, 10:50:33 am »
There's a good chance that you'll get whole set of date functions in 1.6.4, so perhaps just wait.
If you're not paying for something, you're not the customer; you're the product being sold.
- Andrew Lewis

Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.

Offline JotEmI

  • Soldier
  • **
  • Posts: 188
Re: Date and time functions
« Reply #2 on: March 16, 2013, 06:50:01 am »
To be honest I'll probably finish my mod before you guys release 1.6.4 :) I only need to add specified number of hours and compare two dates so I'll just implement it myself for now.

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: Date and time functions
« Reply #3 on: March 16, 2013, 09:55:28 am »
I made a function a while ago which returns the number of seconds (or however much accuracy) since a reference by simply by converting multiple results of FormatDate into a number, multiplying most by a factor, and then adding them. I'll take a look for it real quick, but I doubt I'll be able to find it.

EDIT: I found not exactly what I'm looking for but I did make some timer related functions at one point. It is attached as time.pas with the following functions:
Code: [Select]
function time_Timer_New(): word;
procedure time_Timer_Delete(const Timer: word);
procedure time_Timer_Start(const Timer: word);
procedure time_Timer_Pause(const Timer: word);
function time_Timer_GetTime(const Timer: word): extended;
function time_Span_FromDays(const Time: extended): int64;
function time_Span_FromHours(const Time: extended): int64;
function time_Span_FromMinutes(const Time: extended): int64;
function time_Span_FromSeconds(const Time: extended): int64;
function time_Span_FromMilliSeconds(const Time: extended): int64;
function time_Span_FromMicroSeconds(const Time: extended): int64;
function time_Span_FromPart(const Time: extended; const Part: byte): int64;
function time_Span_GetTotalDays(const Time: int64): extended;
function time_Span_GetTotalHours(const Time: int64): extended;
function time_Span_GetTotalMinutes(const Time: int64): extended;
function time_Span_GetTotalSeconds(const Time: int64): extended;
function time_Span_GetTotalMilliSeconds(const Time: int64): extended;
function time_Span_GetTotalMicroSeconds(const Time: int64): extended;
function time_Span_GetTotalPart(const Time: int64; const Part: byte): extended;
function time_Span_GetDays(const Time: int64): int64;
function time_Span_GetHours(const Time: int64): int64;
function time_Span_GetMinutes(const Time: int64): int64;
function time_Span_GetSeconds(const Time: int64): int64;
function time_Span_GetMilliSeconds(const Time: int64): int64;
function time_Span_GetMicroSeconds(const Time: int64): int64;
function time_Span_GetPart(const Time: int64; const Part: byte): int64;
function time_Span_LabelPart(const Part: byte): string;
function time_Span_ToStringOpt(Time: int64; const LowerPartBound, UpperPartBound: byte): string;
function time_Span_ToString(const Time: int64): string;

EDIT2: I found what I was origonally looking for. Here it is:
Code: [Select]
function MonthDays(const Month: byte): byte;
begin
  case (Month) of
    1, 3, 5, 7, 9, 11: Result := 31;
    4, 6, 8, 10, 12: Result := 30;
    2: Result := 28;
  end;
end;

function GetTime: cardinal;
begin
  Result := 31536000000 * (StrtoInt(FormatDate('y')) - 2008) + 86400000 * MonthDays(StrtoInt(FormatDate('m'))) * StrtoInt(FormatDate('m')) + 86400000 * StrtoInt(FormatDate('d')) + 3600000 * StrtoInt(FormatDate('h')) + 60000 * StrtoInt(FormatDate('n')) + 1000 * StrtoInt(FormatDate('s')) + StrtoInt(FormatDate('zzz'));
end;
« Last Edit: March 16, 2013, 10:08:25 am by DorkeyDear »

Offline JotEmI

  • Soldier
  • **
  • Posts: 188
Re: Date and time functions
« Reply #4 on: March 16, 2013, 11:55:38 am »
Thx, I'll be sure to look into it.

EDIT:
After all I've decided to create a structure similar to the DateTime class in .NET. I've used the standard Julian Day Number to calculate time difference in days, hours, minutes and seconds.

Snippets:
Code: [Select]
type TDateTime=record
Year: integer;
Month: integer;
Day: integer;
Hour: integer;
Minute: integer;
Second: integer;
end;

...

//JDN() - returns Julian Day Number from date
function JDN(date: TDateTime): integer;
begin
Result:=(367*date.Year)-7*(date.Year+(date.Month+9)/12)/4-3*((date.Year+(date.Month-9)/7)/100+1)/4+275*date.Month/9+date.Day+1721029;
end;

//DateDiff() - returns difference between two dates
//Date part:
//year or y - difference of years
//month or m - difference of months
//day or d - difference of days
//hour or h - difference of hours
//minute or m - difference of minutes
//second or s - difference of seconds
function DateDiff(datepart: string; date1,date2: TDateTime): integer;
var
r,days,hours,minutes: integer;
d1,d2: TDateTime;
begin
r:=0;
d1:=date1;
d2:=date2;
if(datepart='year')or(datepart='y')then r:=d2.Year-d1.Year
else if(datepart='month')or(datepart='M')then r:=((d2.Year-d1.Year)*12)+(d2.Month-d1.Month)
else if(datepart='day')or(datepart='d')then r:=JDN(d2)-JDN(d1)
else if(datepart='hour')or(datepart='h')then r:=(JDN(d2)-JDN(d1))*24+(d2.Hour-d1.Hour)
else if(datepart='minute')or(datepart='m')then
begin
days:=JDN(d2)-JDN(d1);
hours:=d2.Hour-d1.Hour;
r:=(days*1440)+(hours*60)+(d2.Minute-d1.Minute);
end
else if(datepart='second')or(datepart='s')then
begin
days:=JDN(d2)-JDN(d1);
hours:=d2.Hour-d1.Hour;
minutes:=d2.Minute-d1.Minute;
r:=(days*86400)+(hours*3600)+(minutes*60)+(d2.Second-d1.Second);
end;
Result:=r;
end;

Complete code with comments is attached below if anyone would like to use it.
Example of usage:
Code: [Select]
var
d1,d2: TDateTime;

d1:=ParseDate(FormatDate('yyyy-MM-dd hh:mm:ss'));
WriteLn(DateToStr(d1,'MM/dd/yyyy hh:mm:ss'));

d2:=DateAdd('day',10,d1);
WriteLn(inttostr(DateDiff('day',d1,d2)));

if(CompareDates(d1,d2)=1)then WriteLn('d1>d2')
else if(CompareDates(d1,d2)=-1)then WriteLn('d1<d2');
« Last Edit: March 16, 2013, 08:46:23 pm by JotEmI »